[{"data":1,"prerenderedAt":599},["ShallowReactive",2],{"cms-blog-scaling-ecs-on-php-fpm-workers":3,"cms-blog":20},{"title":4,"excerpt":5,"slug":8,"rawDate":9,"date":10,"modified":11,"content":12,"readingTime":13,"acf":14,"tags":17,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Scaling ECS on PHP-FPM workers instead of CPU and memory",{"raw":6,"plain":7},"\u003Cp>Our ECS services scaled on CPU and memory, which meant traffic spikes took the platform down before a new container ever started. Scaling on busy PHP-FPM workers fixed the outages and let us run 3 containers instead of 8.\u003C\u002Fp>","Our ECS services scaled on CPU and memory, which meant traffic spikes took the platform down before a new container ever started. Scaling on busy PHP-FPM workers fixed the outages and let us run 3 containers instead of 8.","scaling-ecs-on-php-fpm-workers","2026-09-15T09:00:00",["Date","2026-09-15T00:00:00.000Z"],["Date","2026-11-06T00:00:00.000Z"],"\u003Cp class=\"wp-block-paragraph\">At work, our main application is a Symfony API running in PHP-FPM containers on AWS ECS (Fargate). For a long time, those services scaled the way most tutorials tell you to: add a task when average CPU or memory crosses a threshold.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It didn’t work. When a traffic spike hit, the application would fall over before ECS had even decided to scale. To cope, we kept a minimum of 8 containers running all the time, which is expensive insurance for a problem it didn’t actually solve.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Why CPU and memory were the wrong signal\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A PHP-FPM container serves requests with a fixed pool of worker processes. Once all workers are busy, new requests queue, and if they queue for long enough, the load balancer gives up on them.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The trouble is that a busy worker isn’t necessarily using much CPU. Plenty of our requests spend most of their time waiting on the database or another API. So you can have every worker tied up, requests timing out, and CPU sat at a comfortable 40%.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Here is how bad that gets. During load testing, I pulled the per-minute CPU for two very different states of the same service. A healthy fleet averaged 41.1%. A fleet that was actively timing out requests averaged 43.2%.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Two percentage points. That’s the entire signal you get between “fine” and “falling over”.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The average hides it because the work is distributed unevenly. In the same minutes, individual containers were pegged at 100% while others sat near idle, and the mean of those looks perfectly relaxed. Target tracking scales on the mean. So it did nothing.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">What we actually cared about was simple: how many FPM workers are busy?\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Publishing FPM active processes to CloudWatch\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">PHP-FPM can expose a status page with exactly that number in it (\u003Ccode>active processes\u003C\u002Fcode>). The work was getting it into CloudWatch so ECS could scale on it.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">We added a small PHP script that runs alongside FPM under supervisord in every container. Every 10 seconds it:\u003C\u002Fp>\n\n\n\n\u003Col class=\"wp-block-list\">\n\u003Cli>reads the FPM status page directly over FastCGI (no web server in the way),\u003C\u002Fli>\n\n\n\n\u003Cli>works out which ECS cluster and service it belongs to from the task metadata endpoint,\u003C\u002Fli>\n\n\n\n\u003Cli>publishes&nbsp;\u003Ccode>FpmActiveProcesses\u003C\u002Fcode>&nbsp;to CloudWatch as a high-resolution metric.\u003C\u002Fli>\n\u003C\u002Fol>\n\n\n\n\u003Cpre class=\"torchlight\">\u003Ccode data-torchlight-id=\"6aa14e0e-6187-2f5a-4fb6-b7f604d08944\">\u003C!-- Syntax highlighted by torchlight.dev -->\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 1\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">$client-&gt;putMetricData([\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 2\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">    'MetricData' =&gt; [[\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 3\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">        'Namespace' =&gt; 'Example\u002FApplication',\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 4\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">        'MetricName' =&gt; 'FpmActiveProcesses',\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 5\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">        'Dimensions' =&gt; [\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 6\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            ['Name' =&gt; 'ClusterName', 'Value' =&gt; $cluster],\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 7\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            ['Name' =&gt; 'ServiceName', 'Value' =&gt; $service],\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 8\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">        ],\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 9\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">        'Value' =&gt; (float) $status['active processes'],\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">10\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">        'Unit' =&gt; 'Count',\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">11\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">        'StorageResolution' =&gt; 1,\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">12\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">    ]],\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">13\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">]);\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fcode>\n    \u003Cdiv class=\"copy-button__container js-copy-to-clipboard-container\">\n      \u003Cdiv class=\"copy-button__text js-copy-to-clipboard-notification\">Copied!\u003C\u002Fdiv>\n      \u003Cbutton type=\"button\" title=\"Copy to clipboard\" class=\"copy-button__button js-copy-to-clipboard-button\">\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n    \u003Cspan class=\"torchlight-copy-target js-copy-to-clipboard-target\" style=\"display: none\">$client-&gt;putMetricData([\n    'MetricData' =&gt; [[\n        'Namespace' =&gt; 'Example\u002FApplication',\n        'MetricName' =&gt; 'FpmActiveProcesses',\n        'Dimensions' =&gt; [\n            ['Name' =&gt; 'ClusterName', 'Value' =&gt; $cluster],\n            ['Name' =&gt; 'ServiceName', 'Value' =&gt; $service],\n        ],\n        'Value' =&gt; (float) $status['active processes'],\n        'Unit' =&gt; 'Count',\n        'StorageResolution' =&gt; 1,\n    ]],\n]);\u003C\u002Fspan>\n    \u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Three details mattered more than I expected.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It doesn’t boot Symfony. The metric matters most when the application is struggling, so the publisher must keep reporting even when the app can’t serve traffic.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It catches its own failures and carries on. When we first shipped it to production, the task role was missing&nbsp;\u003Ccode>cloudwatch:PutMetricData\u003C\u002Fcode>, so every call was rejected. Because the script logs the error and keeps looping, the moment the permission was granted, it started publishing on the containers that were already running. No redeploy.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">And every container publishes its own datapoint under the same service. CloudWatch’s average across tasks then gives “busy workers per container”, which falls as tasks are added.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">One quirk worth knowing: the metric never reads zero. The publisher polls the status page over FastCGI, and that request is itself an active process, so the floor is exactly 1. If you set a scale-in threshold at or below 1, scale-in will never fire, and your fleet will ratchet up forever. I know this because I nearly did it.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Step scaling, not target tracking\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">My first instinct was a target tracking policy. Pick a target number of busy workers, let AWS do the rest.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">For our custom FPM metric, target tracking’s managed alarms couldn’t provide the 10-second evaluation period we wanted. Step scaling gave me control over the alarm configuration and the size of each scaling adjustment.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Step scaling lets you bring your own alarm, and the alarm can be high-resolution. Ours:\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"torchlight\">\u003Ccode data-torchlight-id=\"9a6bbe11-114a-c969-cdf0-d89fe6c73046\">\u003C!-- Syntax highlighted by torchlight.dev -->\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 1\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">scale out   FpmActiveProcesses &gt; 5\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 2\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            period 10s, 2 of 3 datapoints\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 3\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            +50% \u002F +100% \u002F +200% \u002F +300%\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 4\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            at 0 \u002F 2.5 \u002F 7.5 \u002F 17.5 over threshold\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 5\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            cooldown 60s\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 6\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 7\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">scale in    FpmActiveProcesses &lt; 1.5\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 8\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            period 60s, 15 evaluation periods\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 9\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            -25%\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">10\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">            cooldown 180s\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fcode>\n    \u003Cdiv class=\"copy-button__container js-copy-to-clipboard-container\">\n      \u003Cdiv class=\"copy-button__text js-copy-to-clipboard-notification\">Copied!\u003C\u002Fdiv>\n      \u003Cbutton type=\"button\" title=\"Copy to clipboard\" class=\"copy-button__button js-copy-to-clipboard-button\">\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n    \u003Cspan class=\"torchlight-copy-target js-copy-to-clipboard-target\" style=\"display: none\">scale out   FpmActiveProcesses &gt; 5\n            period 10s, 2 of 3 datapoints\n            +50% \u002F +100% \u002F +200% \u002F +300%\n            at 0 \u002F 2.5 \u002F 7.5 \u002F 17.5 over threshold\n            cooldown 60s\n\nscale in    FpmActiveProcesses &lt; 1.5\n            period 60s, 15 evaluation periods\n            -25%\n            cooldown 180s\u003C\u002Fspan>\n    \u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Five active workers might sound low when each container has a pool of 40, but that was deliberate. With new containers taking over a minute to become available in our earlier tests, we wanted to scale long before the existing workers became saturated.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The step adjustments matter as much as the speed. A burst that takes you slightly over threshold gets 50% more containers. One that takes you a long way over gets 300%. You don’t crawl up one task at a time while requests pile up.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">On the old CPU policy, the first scaling action after a load test began arrived 5 minutes 20 seconds in. With the high-resolution alarm, I measured the gap between the alarm changing state and Application Auto Scaling acting on it at&nbsp;\u003Cstrong>0.2 seconds\u003C\u002Fstrong>. Capacity was in place 73 seconds later, almost all of which was container boot.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">That shifts the whole problem. AWS acts almost immediately once the alarm fires, and most of the remaining delay is waiting for new containers to become available.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Making new containers start faster\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">So we looked at boot time. Measured on a staging environment:\u003C\u002Fp>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Boot time: 56s to 33s\u003C\u002Fli>\n\n\n\n\u003Cli>Image pull: 27s to 4.7s, by publishing a&nbsp;\u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fsoci-snapshotter\" target=\"_blank\" rel=\"noreferrer noopener\">SOCI index\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=32\u002Fimg\u002Ffavicons\u002Fgithub.com.png\" alt=\"github.com favicon\">\u003C\u002Fpicture>\u003C\u002Fa>&nbsp;so Fargate can lazy-load the image\u003C\u002Fli>\n\n\n\n\u003Cli>Image size: 1.59GB to 1.33GB. A recursive&nbsp;\u003Ccode>chown\u003C\u002Fcode>&nbsp;in the Dockerfile was rewriting every application file into a new layer, so the image carried the whole application twice\u003C\u002Fli>\n\n\n\n\u003Cli>OPcache preload: 600 bytes to 68MB. Our configuration was wrong, so PHP had been silently ignoring it\u003C\u002Fli>\n\u003C\u002Ful>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">The deploy that wouldn’t deploy\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The first production release of all this failed and rolled back, which was a useful lesson in measuring the right thing.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The containers were fine. They were serving&nbsp;\u003Ccode>200\u003C\u002Fcode>s within 52 seconds. But the target group was configured with&nbsp;\u003Ccode>healthy_threshold = 4\u003C\u002Fcode>&nbsp;and a 10-second interval, so a container had to pass four consecutive checks before the load balancer would call it healthy. That’s 40 seconds of passing checks on top of the 52 to start.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">ECS gives a new task a grace period before it will act on health check failures. Ours was 30 seconds.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The task reached its third passing check at 72 seconds and was killed. The fourth, which would have marked it healthy, would have landed at 80.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It missed by eight seconds.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">We raised the grace period to 120 seconds and brought the thresholds in line with our other environments (5-second interval,&nbsp;\u003Ccode>healthy_threshold = 2\u003C\u002Fcode>). Time to healthy went from 67–82 seconds down to 32–57. The same deploy went out cleanly twenty minutes later.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Worth noting that&nbsp;\u003Ccode>healthy_threshold\u003C\u002Fcode>&nbsp;and&nbsp;\u003Ccode>unhealthy_threshold\u003C\u002Fcode>&nbsp;pull in opposite directions here.&nbsp;\u003Ccode>4 × 10s\u003C\u002Fcode>&nbsp;and&nbsp;\u003Ccode>8 × 5s\u003C\u002Fcode>&nbsp;are both a 40-second failure budget, so switching to the faster interval cost us nothing on that side while halving the time to recognise a good container.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">What we got wrong\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The scale-in policy, twice.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">We started at&nbsp;\u003Ccode>&lt; 2.5\u003C\u002Fcode>&nbsp;over 5 evaluation periods. The fleet promptly started shedding containers in the middle of busy periods, because FPM sits near its floor between bursts and five minutes of “quiet” is easy to find at our average requests a minute. We got&nbsp;\u003Cstrong>nine capacity changes in 45 minutes\u003C\u002Fstrong>, and one of them removed a container ninety seconds before a burst arrived. p95 went to 21.5 seconds, and we served our only 5xx of the day.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Lowering the threshold to 1.5 and stretching the window to 15 evaluation periods fixed it. The fleet held steady for five hours through the busiest part of the day, then came down cleanly in the evening.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">But that created a subtler problem, which took another week to notice. Scale-in triggers when the&nbsp;\u003Cem>per-container\u003C\u002Fem>&nbsp;average drops below the threshold, so the condition is really “total work below&nbsp;\u003Ccode>1.5 × containers\u003C\u002Fcode>“. At nine containers, we were averaging around 1.66 active processes each. That’s low utilisation, but still above our 1.5 scale-in threshold. As a result, the fleet couldn’t shrink until traffic dropped further. Because every container also contributes a baseline reading of one, the threshold needs to account for both actual application work and the monitoring request itself.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It self-corrects overnight, so we’ve left it. But if you build this, be aware that a per-container metric with a fixed threshold has a dead zone, and it gets wider the bigger your fleet is.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">One more thing that wasn’t scaling at all\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">While investigating, we found production was using&nbsp;\u003Ccode>round_robin\u003C\u002Fcode>&nbsp;to distribute requests across containers.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Round robin distributes requests evenly. It does not distribute&nbsp;\u003Cem>work\u003C\u002Fem>&nbsp;evenly, and when some of your requests take 30 seconds, one unlucky container ends up holding several of them while its neighbours idle. On staging, switching to least outstanding requests took p95 from 6.16s to 3.52s and collapsed the spread in per-container CPU from about 48 percentage points to 7.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">The results\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The floor went from&nbsp;\u003Cstrong>8 containers to 3\u003C\u002Fstrong>, and it’s been there for a month. On a typical weekday, the fleet now sits between 3 and 6, and scales to 9 when something expensive arrives.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The day we dropped the floor, two production releases went out onto a 3-container fleet during the morning ramp, and the FPM listen queue never left zero. Over 1,020 samples of that queue across two days, it was non-zero exactly three times, always with a value of 1. One request waiting, briefly.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A few days later,&nbsp;\u003Cstrong>6 containers absorbed a substantial requests-per-minute peak with a better p95 than 8 containers had been giving us\u003C\u002Fstrong>. That’s the part I’d point at if you’re wondering whether this is worth doing. Not the cost saving. The fact that a smaller fleet, scaled on the right signal, outperformed a larger one scaled on the wrong one.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">\u003Cstrong>Scale on the thing that actually runs out.\u003C\u002Fstrong>&nbsp;For a PHP-FPM app, that’s workers, not CPU.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">\u003C\u002Fp>",9,{"project_url":15,"github":15,"icons":16},"",[],[],"Joe",null,[21,129,253,367,471,578],[22,34,41,52,63,74,85,97,109,119],{"title":23,"excerpt":24,"slug":27,"date":28,"modified":29,"readingTime":30,"acf":31,"tags":33,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How AI helped me add my Mitsubishi Delica D:5 to UK insurance databases",{"raw":25,"plain":26},"\u003Cp>Earlier this year I bought a 2007 Mitsubishi Delica D:5. The D:5 has been sold in Japan since 2007 but was never officially sold in the UK. Mine is a Japanese import, which means that while it is perfectly legal and registered with the DVLA, getting insurance for it can be a little more complicated [&hellip;]\u003C\u002Fp>","Earlier this year I bought a 2007 Mitsubishi Delica D:5. The D:5 has been sold in Japan since 2007 but was never officially sold in the UK. Mine is a Japanese import, which means that while it is perfectly legal and registered with the DVLA, getting insurance for it can be a little more complicated […]","how-ai-helped-me-add-my-mitsubishi-delica-d5-to-uk-insurance-databases",["Date","2026-11-06T00:00:00.000Z"],["Date","2026-11-06T00:00:00.000Z"],8,{"project_url":15,"github":15,"icons":32},[],[],{"title":4,"excerpt":35,"slug":8,"date":36,"modified":37,"readingTime":13,"acf":38,"tags":40,"author":18,"featuredMediaUrl":19,"featuredMedia":19},{"raw":6,"plain":7},["Date","2026-09-15T00:00:00.000Z"],["Date","2026-11-06T00:00:00.000Z"],{"project_url":15,"github":15,"icons":39},[],[],{"title":42,"excerpt":43,"slug":46,"date":47,"modified":48,"readingTime":49,"acf":50,"tags":51,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How to download a Google Sheet on a cron",{"raw":44,"plain":45},"\u003Cp>Working with Google Cloud can be confusing for beginners and sometimes all you need is to manipulate a Google Sheet. I have a couple of use cases for downloading a sheet and uploading a sheet. I haven&#8217;t quite figured out the upload part yet, but I have got downloading to work. I&#8217;ve decided to write [&hellip;]\u003C\u002Fp>","Working with Google Cloud can be confusing for beginners and sometimes all you need is to manipulate a Google Sheet. I have a couple of use cases for downloading a sheet and uploading a sheet. I haven’t quite figured out the upload part yet, but I have got downloading to work. I’ve decided to write […]","how-to-download-a-google-sheet-on-a-cron",["Date","2024-02-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],4,{"project_url":15,"github":15,"icons":15},[],{"title":53,"excerpt":54,"slug":57,"date":58,"modified":59,"readingTime":60,"acf":61,"tags":62,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How to add Custom Variables to LiveChat",{"raw":55,"plain":56},"\u003Cp>I had a task to add a Google Analytics ID to the user profile in LiveChat. We wanted to be able to match up the person we were chatting to with the analytics data in Google. This looked really simple according to their docs. You can just use the following function: What their docs failed [&hellip;]\u003C\u002Fp>","I had a task to add a Google Analytics ID to the user profile in LiveChat. We wanted to be able to match up the person we were chatting to with the analytics data in Google. This looked really simple according to their docs. You can just use the following function: What their docs failed […]","how-to-add-custom-variables-to-livechat",["Date","2024-01-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],1,{"project_url":15,"github":15,"icons":15},[],{"title":64,"excerpt":65,"slug":68,"date":69,"modified":70,"readingTime":71,"acf":72,"tags":73,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"This one Nuxt trick prevents broken deploys",{"raw":66,"plain":67},"\u003Cp>Have you ever experienced broken deploys while using Nuxt? It can be frustrating when your build encounters errors, but still proceeds to deploy all the files, resulting in broken pages on your website. Fortunately, I discovered a handy Nuxt trick that prevents such broken deploys and ensures a more reliable deployment process. In my case, [&hellip;]\u003C\u002Fp>","Have you ever experienced broken deploys while using Nuxt? It can be frustrating when your build encounters errors, but still proceeds to deploy all the files, resulting in broken pages on your website. Fortunately, I discovered a handy Nuxt trick that prevents such broken deploys and ensures a more reliable deployment process. In my case, […]","this-one-nuxt-trick-prevents-broken-deploys",["Date","2023-07-12T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],2,{"project_url":15,"github":15,"icons":15},[],{"title":75,"excerpt":76,"slug":79,"date":80,"modified":81,"readingTime":82,"acf":83,"tags":84,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"The importance of read time for blog posts and how to automatically generate it using Node.js",{"raw":77,"plain":78},"\u003Cp>In today&#8217;s fast-paced digital world, attention spans are getting shorter, and users often have limited time to consume content. As a result, providing readers with an estimated reading time can be a valuable feature for any blog or content-based website. Why having a read time for a blog post is important Automatically generate a read [&hellip;]\u003C\u002Fp>","In today’s fast-paced digital world, attention spans are getting shorter, and users often have limited time to consume content. As a result, providing readers with an estimated reading time can be a valuable feature for any blog or content-based website. Why having a read time for a blog post is important Automatically generate a read […]","the-importance-of-read-time-for-blog-posts-and-how-to-automatically-generate-it-using-node-js",["Date","2023-06-20T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],3,{"project_url":15,"github":15,"icons":15},[],{"title":86,"excerpt":87,"slug":90,"date":91,"modified":92,"readingTime":30,"acf":93,"tags":94,"author":18,"featuredMediaUrl":95,"featuredMedia":96},"Adding syntax highlighting to my blog with Torchlight",{"raw":88,"plain":89},"\u003Cp>Background A little while ago I read the following blog post, Web Component for a Code Block by Chris Coyier, it got me thinking about how I could enhance the code blocks on my website. This is a tech blog after all, and from time to time I want to share tips and tricks which involve [&hellip;]\u003C\u002Fp>","Background A little while ago I read the following blog post, Web Component for a Code Block by Chris Coyier, it got me thinking about how I could enhance the code blocks on my website. This is a tech blog after all, and from time to time I want to share tips and tricks which involve […]","adding-syntax-highlighting-to-my-blog-with-torchlight",["Date","2023-06-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe1e861af4f6259527d0fc8ad9790f0070bbbbc9e3026b722390c4894a9472d28\u002Fe1e861af4f625952-NVIDIA-GeForce-Overlay-DT-2023-06-16-14.07.00-1.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe1e861af4f6259527d0fc8ad9790f0070bbbbc9e3026b722390c4894a9472d28\u002Fe1e861af4f625952-NVIDIA-GeForce-Overlay-DT-2023-06-16-14.07.00-1.png",{"title":98,"excerpt":99,"slug":102,"date":103,"modified":104,"readingTime":49,"acf":105,"tags":106,"author":18,"featuredMediaUrl":107,"featuredMedia":108},"Adding Algolia search to my 404 page",{"raw":100,"plain":101},"\u003Cp>My site is pretty small, so I don&#8217;t really need search functionality, but the Netlify Algolia plugin looked easy enough to use and a bit of fun. Diving into the docs, I got a bit overwhelmed. Algolia&#8217;s breadth of capabilities is huge. They definitely seem like the go-to for fully customisable search on a Jamstack [&hellip;]\u003C\u002Fp>","My site is pretty small, so I don’t really need search functionality, but the Netlify Algolia plugin looked easy enough to use and a bit of fun. Diving into the docs, I got a bit overwhelmed. Algolia’s breadth of capabilities is huge. They definitely seem like the go-to for fully customisable search on a Jamstack […]","adding-algolia-search-to-my-404-page",["Date","2023-06-13T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F109426a35d77479e1e989a82f03158349304fd98349223e9939110f26ef80377\u002F109426a35d77479e-NVIDIA-GeForce-Overlay-DT-2023-06-13-21.09.10.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F109426a35d77479e1e989a82f03158349304fd98349223e9939110f26ef80377\u002F109426a35d77479e-NVIDIA-GeForce-Overlay-DT-2023-06-13-21.09.10.png",{"title":110,"excerpt":111,"slug":114,"date":115,"modified":116,"readingTime":60,"acf":117,"tags":118,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Dragging to Scroll with JavaScript",{"raw":112,"plain":113},"\u003Cp>My portfolio has some cards to showcase projects and blog posts. On mobile, these cards display in a horizontal slider, which is easy enough to scroll on a touchscreen, or trackpad, but what if someone is viewing the website at a small size on a device with a mouse? Well they can of course use [&hellip;]\u003C\u002Fp>","My portfolio has some cards to showcase projects and blog posts. On mobile, these cards display in a horizontal slider, which is easy enough to scroll on a touchscreen, or trackpad, but what if someone is viewing the website at a small size on a device with a mouse? Well they can of course use […]","dragging-to-scroll-with-javascript",["Date","2023-03-30T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":120,"excerpt":121,"slug":124,"date":125,"modified":126,"readingTime":71,"acf":127,"tags":128,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How To Secure your server using UFW and Cloudflare",{"raw":122,"plain":123},"\u003Cp>This guide will help you use UFW (uncomplicated firewall) to block all traffic to your server other than traffic coming via Cloudflare, or for essential operations such as FTP and SSH. Why would you want to do this? Cloudflare will protect your site from all manner of attacks. However, your server may still be vulnerable. [&hellip;]\u003C\u002Fp>","This guide will help you use UFW (uncomplicated firewall) to block all traffic to your server other than traffic coming via Cloudflare, or for essential operations such as FTP and SSH. Why would you want to do this? Cloudflare will protect your site from all manner of attacks. However, your server may still be vulnerable. […]","how-to-secure-your-server-using-ufw-and-cloudflare",["Date","2021-01-11T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],[130,144,157,170,180,190,204,216,229,239],{"title":131,"excerpt":132,"slug":135,"date":136,"modified":137,"readingTime":60,"acf":138,"tags":143,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Adobe XD Challenge Calculator",{"raw":133,"plain":134},"\u003Cp>The third challenge was to create a calculator. I wanted to practise my CSS art and so chose an image of an old Casio calculator and tried to recreate it as closely as possible. It was quite a challenge creating the code for the calculator to function. It wasn&#8217;t as simple as just adding numbers [&hellip;]\u003C\u002Fp>","The third challenge was to create a calculator. I wanted to practise my CSS art and so chose an image of an old Casio calculator and tried to recreate it as closely as possible. It was quite a challenge creating the code for the calculator to function. It wasn’t as simple as just adding numbers […]","adobe-xd-challenge-calculator",["Date","2020-08-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":139,"github":140,"icons":141},"https:\u002F\u002Fvue-calculator-joe.netlify.app","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FVue-Calculator",[142],"Vue",[],{"title":145,"excerpt":146,"slug":149,"date":150,"modified":151,"readingTime":60,"acf":152,"tags":156,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Adobe XD Challenge Fitness App",{"raw":147,"plain":148},"\u003Cp>The second challenge was to create a fitness app. I chose to make an activity tracker. I took inspiration from Lifelog, an app by Sony that I used for many years. I used the Google Maps API and created a component in Vue for the activities.\u003C\u002Fp>","The second challenge was to create a fitness app. I chose to make an activity tracker. I took inspiration from Lifelog, an app by Sony that I used for many years. I used the Google Maps API and created a component in Vue for the activities.","adobe-xd-challenge-fitness-app",["Date","2020-08-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":153,"github":154,"icons":155},"https:\u002F\u002Fjoe-exercise.netlify.app","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FExercise-App",[142],[],{"title":158,"excerpt":159,"slug":162,"date":163,"modified":164,"readingTime":60,"acf":165,"tags":169,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Adobe XD Challenge – Music Player",{"raw":160,"plain":161},"\u003Cp>Me and Eleanor Morgan participated in the Adobe XD Challenge. I wanted to use Vue.js rather than practise my skills in XD as I view myself as more of a developer than a designer. The first challenge was to create a music player. I played around with the audio API and used some CSS animations.\u003C\u002Fp>","Me and Eleanor Morgan participated in the Adobe XD Challenge. I wanted to use Vue.js rather than practise my skills in XD as I view myself as more of a developer than a designer. The first challenge was to create a music player. I played around with the audio API and used some CSS animations.","adobe-xd-challenge-music-player",["Date","2020-08-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":166,"github":167,"icons":168},"http:\u002F\u002Fmusic-player.joebailey.xyz\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002Fmusic-player",[142],[],{"title":171,"excerpt":172,"slug":175,"date":176,"modified":177,"readingTime":82,"acf":178,"tags":179,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"React and Vue re-visited",{"raw":173,"plain":174},"\u003Cp>After re-creating my portfolio with Gatsby (which uses React) and building an app for a client in Vue I feel I have more knowledge about the two JavaScript frameworks to give an informed opinion on both. When I was first starting out using these sort of frameworks I wrote this article on my thoughts. I [&hellip;]\u003C\u002Fp>","After re-creating my portfolio with Gatsby (which uses React) and building an app for a client in Vue I feel I have more knowledge about the two JavaScript frameworks to give an informed opinion on both. When I was first starting out using these sort of frameworks I wrote this article on my thoughts. I […]","react-and-vue-re-visited",["Date","2020-05-09T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":181,"excerpt":182,"slug":185,"date":186,"modified":187,"readingTime":71,"acf":188,"tags":189,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"What is a Front-End Developer?",{"raw":183,"plain":184},"\u003Cp>I&#8217;ve been asking myself this question a lot recently after applying for quite a few web development placements. The experience has been enlightening, teaching me a great deal about the industry. I&#8217;ve been reflecting on what I&#8217;m good at in web development and what I enjoy. Whilst freelancing I&#8217;d describe myself as a Full-Stack Developer. [&hellip;]\u003C\u002Fp>","I’ve been asking myself this question a lot recently after applying for quite a few web development placements. The experience has been enlightening, teaching me a great deal about the industry. I’ve been reflecting on what I’m good at in web development and what I enjoy. Whilst freelancing I’d describe myself as a Full-Stack Developer. […]","what-is-a-front-end-developer",["Date","2020-05-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":191,"excerpt":192,"slug":195,"date":196,"modified":197,"readingTime":60,"acf":198,"tags":203,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Points Of Interest",{"raw":193,"plain":194},"\u003Cp>Following on from developing the HitTastic! site we had to create a site in PHP that allows users to view POI&#8217;s stored in a database, and contribute to this database. We had to do some basic styles to go along with it.\u003C\u002Fp>","Following on from developing the HitTastic! site we had to create a site in PHP that allows users to view POI’s stored in a database, and contribute to this database. We had to do some basic styles to go along with it.","points-of-interest",["Date","2020-04-28T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":199,"github":200,"icons":201},"https:\u002F\u002Fpoi.joebailey.xyz\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FPointsOfInterest-MySQLi",[202],"PHP",[],{"title":205,"excerpt":206,"slug":209,"date":210,"modified":211,"readingTime":60,"acf":212,"tags":215,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"HitTastic!",{"raw":207,"plain":208},"\u003Cp>In my second year of university, I did a PHP unit where we were tasked with creating a site showing the number one songs from a certain year. We had to make a login, connect to a database, and perform a search.\u003C\u002Fp>","In my second year of university, I did a PHP unit where we were tasked with creating a site showing the number one songs from a certain year. We had to make a login, connect to a database, and perform a search.","hittastic",["Date","2020-04-28T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":213,"icons":214},"https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FPHP-Lessons",[202],[],{"title":217,"excerpt":218,"slug":221,"date":222,"modified":223,"readingTime":60,"acf":224,"tags":228,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Hangman",{"raw":219,"plain":220},"\u003Cp>Whilst I was searching for a placement I had a few tasks to complete for various roles I was interviewing for. One of these tasks was to create a simple Hangman game in PHP.\u003C\u002Fp>","Whilst I was searching for a placement I had a few tasks to complete for various roles I was interviewing for. One of these tasks was to create a simple Hangman game in PHP.","hangman",["Date","2020-04-28T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":225,"github":226,"icons":227},"https:\u002F\u002Fhangman.joebailey.xyz\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FHangman",[202],[],{"title":230,"excerpt":231,"slug":234,"date":235,"modified":236,"readingTime":71,"acf":237,"tags":238,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Re-creating my portfolio with Gatsby",{"raw":232,"plain":233},"\u003Cp>You may have read Re-creating my portfolio with React where I talked about my experiences converting my simple static portfolio into a React website, turning reusable objects on the page into React components. This inspired me to learn Gatsby, a static site generator that uses React. I was previously using my a category on my [&hellip;]\u003C\u002Fp>","You may have read Re-creating my portfolio with React where I talked about my experiences converting my simple static portfolio into a React website, turning reusable objects on the page into React components. This inspired me to learn Gatsby, a static site generator that uses React. I was previously using my a category on my […]","re-creating-my-portfolio-with-gatsby",["Date","2020-04-27T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":240,"excerpt":241,"slug":244,"date":245,"modified":246,"readingTime":60,"acf":247,"tags":252,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Firebase Chat App",{"raw":242,"plain":243},"\u003Cp>In my first year of University I had a go at creating a chat app using Firebase following my lecturers instructions. I was the only person in my class to succeed. Go ahead, type something.\u003C\u002Fp>","In my first year of University I had a go at creating a chat app using Firebase following my lecturers instructions. I was the only person in my class to succeed. Go ahead, type something.","firebase-chat-app",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":248,"github":249,"icons":250},"https:\u002F\u002Fchat-app-a7f51.firebaseapp.com\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002Ffirebase_chat_app",[251],"Firebase",[],[254,268,281,295,305,315,325,335,345,355],{"title":255,"excerpt":256,"slug":259,"date":260,"modified":261,"readingTime":60,"acf":262,"tags":267,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"React Tic Tac Toe",{"raw":257,"plain":258},"\u003Cp>My first venture into the world of React was building this Tic Tac Toe game using the React Docs. It also helped me get to grips with CodePen for creating small little projects.\u003C\u002Fp>","My first venture into the world of React was building this Tic Tac Toe game using the React Docs. It also helped me get to grips with CodePen for creating small little projects.","react-tic-tac-toe",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":263,"github":264,"icons":265},"https:\u002F\u002Fcodepen.io\u002Fjoebailey26\u002Fpen\u002FpoogwjN","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FReact-Tic-Tac-Toe",[266],"React",[],{"title":269,"excerpt":270,"slug":273,"date":274,"modified":275,"readingTime":60,"acf":276,"tags":280,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Vue To-Do List",{"raw":271,"plain":272},"\u003Cp>After experimenting using Vue in my Photography Website I decided to have a go at making a To-Do List. You can create and delete To Dos but they don&#8217;t currently persist. This is something I wish to add in the future.\u003C\u002Fp>","After experimenting using Vue in my Photography Website I decided to have a go at making a To-Do List. You can create and delete To Dos but they don’t currently persist. This is something I wish to add in the future.","vue-to-do-list",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":277,"github":278,"icons":279},"https:\u002F\u002Frelaxed-cori-9310e4.netlify.app\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FVue-To-Do-List",[142],[],{"title":282,"excerpt":283,"slug":286,"date":287,"modified":288,"readingTime":60,"acf":289,"tags":294,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"To-Do List",{"raw":284,"plain":285},"\u003Cp>As part of my university course we were tasked with creating a To Do List in Vanilla JavaScript. For many, it was also an introduction into using NPM and BrowserSync for the first time. We also experimented with using Local Browser Storage.\u003C\u002Fp>","As part of my university course we were tasked with creating a To Do List in Vanilla JavaScript. For many, it was also an introduction into using NPM and BrowserSync for the first time. We also experimented with using Local Browser Storage.","to-do-list",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":290,"github":291,"icons":292},"https:\u002F\u002Fcodepen.io\u002Fjoebailey26\u002Fpen\u002FwvvbBpN","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FJavaScript-To-Do-List",[293],"Custom",[],{"title":296,"excerpt":297,"slug":300,"date":301,"modified":302,"readingTime":60,"acf":303,"tags":304,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Re-creating my Portfolio with React",{"raw":298,"plain":299},"\u003Cp>I&#8217;ve just finished recreating my portfolio using React. There aren&#8217;t very many visual changes apart from changing the hover effects a little. The site features a lot of repetitive content, such as portfolio items. React is good for this because I can create a component for the item which minimizes the amount of coding required. [&hellip;]\u003C\u002Fp>","I’ve just finished recreating my portfolio using React. There aren’t very many visual changes apart from changing the hover effects a little. The site features a lot of repetitive content, such as portfolio items. React is good for this because I can create a component for the item which minimizes the amount of coding required. […]","re-creating-my-portfolio-with-react",["Date","2020-02-03T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":306,"excerpt":307,"slug":310,"date":311,"modified":312,"readingTime":71,"acf":313,"tags":314,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"A new Portfolio with Vue.js – Joe Bailey Photography",{"raw":308,"plain":309},"\u003Cp>To mark the beginning of my second year at University I thought that I would try learning a new skill, namely Vue.js. I usually struggle to learn something if I don&#8217;t see any real practical application for it, but this time I figured I could turn my photography portfolio into a dynamic Vue.js enhanced page. [&hellip;]\u003C\u002Fp>","To mark the beginning of my second year at University I thought that I would try learning a new skill, namely Vue.js. I usually struggle to learn something if I don’t see any real practical application for it, but this time I figured I could turn my photography portfolio into a dynamic Vue.js enhanced page. […]","a-new-portfolio-with-vue-js",["Date","2019-12-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":316,"excerpt":317,"slug":320,"date":321,"modified":322,"readingTime":60,"acf":323,"tags":324,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Cookie Consent – Joe Bailey Photography",{"raw":318,"plain":319},"\u003Cp>Over the past couple of months, I&#8217;ve added some Analytics software to my site such as Google Analytics and Facebook Pixel. As my website serves customers in the EU, the Cookie Law applies. I have used JavaScript to ensure that cookies are not fired until the user has explicitly accepted them on the website. A [&hellip;]\u003C\u002Fp>","Over the past couple of months, I’ve added some Analytics software to my site such as Google Analytics and Facebook Pixel. As my website serves customers in the EU, the Cookie Law applies. I have used JavaScript to ensure that cookies are not fired until the user has explicitly accepted them on the website. A […]","cookie-consent",["Date","2019-12-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":326,"excerpt":327,"slug":330,"date":331,"modified":332,"readingTime":71,"acf":333,"tags":334,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Re-doing my portfolio",{"raw":328,"plain":329},"\u003Cp>I built my web design portfolio site over the Christmas of 2018 and decided it needed a bit of a refresh during the summer. I got in touch with the @_tashhockey, the person behind Honest Feedback, to give my website a bit of a review. She made some really good points and brought to light [&hellip;]\u003C\u002Fp>","I built my web design portfolio site over the Christmas of 2018 and decided it needed a bit of a refresh during the summer. I got in touch with the @_tashhockey, the person behind Honest Feedback, to give my website a bit of a review. She made some really good points and brought to light […]","re-doing-my-portfolio",["Date","2019-10-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":336,"excerpt":337,"slug":340,"date":341,"modified":342,"readingTime":60,"acf":343,"tags":344,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Animated mobile menu",{"raw":338,"plain":339},"\u003Cp>In quite a few of my projects I&#8217;ve needed a quick and easy way of making a menu which scales onto mobile. I like the style that android apps have; the animated drawer, so I have replicated this. The menu is swipe aware using Hammer.js which means if you swipe right on mobile then the [&hellip;]\u003C\u002Fp>","In quite a few of my projects I’ve needed a quick and easy way of making a menu which scales onto mobile. I like the style that android apps have; the animated drawer, so I have replicated this. The menu is swipe aware using Hammer.js which means if you swipe right on mobile then the […]","animated-mobile-menu",["Date","2019-09-30T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":346,"excerpt":347,"slug":350,"date":351,"modified":352,"readingTime":60,"acf":353,"tags":354,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"No scroll whilst lightbox is open – Joe Bailey Photography",{"raw":348,"plain":349},"\u003Cp>I read the following article by CSS Tricks https:\u002F\u002Fcss-tricks.com\u002Fprevent-page-scrolling-when-a-modal-is-open\u002F and decided that my website shouldn&#8217;t scroll whilst the lightbox is shown, i.e. on the Blog and the Memories pages when an image is clicked. I use the Featherlight plugin on my Blog and the equivalent for the Memories page. I added the following CSS to [&hellip;]\u003C\u002Fp>","I read the following article by CSS Tricks https:\u002F\u002Fcss-tricks.com\u002Fprevent-page-scrolling-when-a-modal-is-open\u002F and decided that my website shouldn’t scroll whilst the lightbox is shown, i.e. on the Blog and the Memories pages when an image is clicked. I use the Featherlight plugin on my Blog and the equivalent for the Memories page. I added the following CSS to […]","no-scroll-whilst-lightbox-is-open",["Date","2019-08-01T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":356,"excerpt":357,"slug":360,"date":361,"modified":362,"readingTime":60,"acf":363,"tags":364,"author":18,"featuredMediaUrl":365,"featuredMedia":366},"Dark Mode – Joe Bailey Photography",{"raw":358,"plain":359},"\u003Cp>I read the following article: https:\u002F\u002Fwww.howtogeek.com\u002F434592\u002Fwhat%E2%80%99s-new-in-chrome-76-arriving-july-30th\u002F and was excited by &#8220;Automatic Dark Mode is Coming to Websites&#8221;. I decided to give it a shot. I read up on the Media Queries Level 5 spec and added the &#8220;prefers-color-scheme&#8221; media query to my CSS. I downloaded a copy of Chrome Canary to test the website, as [&hellip;]\u003C\u002Fp>","I read the following article: https:\u002F\u002Fwww.howtogeek.com\u002F434592\u002Fwhat%E2%80%99s-new-in-chrome-76-arriving-july-30th\u002F and was excited by “Automatic Dark Mode is Coming to Websites”. I decided to give it a shot. I read up on the Media Queries Level 5 spec and added the “prefers-color-scheme” media query to my CSS. I downloaded a copy of Chrome Canary to test the website, as […]","dark-mode",["Date","2019-07-29T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F18ef7e8b3ffaa78e6531a8e7db4678f61b89f836e42519209287c63e325266b7\u002F18ef7e8b3ffaa78e-dark-mode.jpg","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F18ef7e8b3ffaa78e6531a8e7db4678f61b89f836e42519209287c63e325266b7\u002F18ef7e8b3ffaa78e-dark-mode.jpg",[368,380,390,399,409,419,429,441,451,461],{"title":369,"excerpt":370,"slug":373,"date":374,"modified":375,"readingTime":60,"acf":376,"tags":377,"author":18,"featuredMediaUrl":378,"featuredMedia":379},"Joe Bailey Photography is now a Progressive Web App",{"raw":371,"plain":372},"\u003Cp>Making my site work offline had been on my bucket list for a while. It was the last thing in Google Chrome&#8217;s Lighthouse test to complete. The site now has close to 100 scores across all areas in Google Chrome&#8217;s Lighthouse Audit. I read up on Service Workers on both Google Developers and MDN Web [&hellip;]\u003C\u002Fp>","Making my site work offline had been on my bucket list for a while. It was the last thing in Google Chrome’s Lighthouse test to complete. The site now has close to 100 scores across all areas in Google Chrome’s Lighthouse Audit. I read up on Service Workers on both Google Developers and MDN Web […]","joe-bailey-photography-is-now-a-progressive-web-app",["Date","2019-07-18T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F5464e472fd92822b761ed6e957448e480b6c12f6291d9ae23f168b154c37439d\u002F5464e472fd92822b-Untitled-1.jpg","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F5464e472fd92822b761ed6e957448e480b6c12f6291d9ae23f168b154c37439d\u002F5464e472fd92822b-Untitled-1.jpg",{"title":381,"excerpt":382,"slug":385,"date":386,"modified":387,"readingTime":60,"acf":388,"tags":389,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Data Flow Diagrams",{"raw":383,"plain":384},"\u003Cp>When we first started doing Data Flow Diagrams at the start of the semester I thought they were the worst thing in the world. However, as I came to understand them more and start to think about more real-world business problems that I was encountering such as creating a website for my Dad or as [&hellip;]\u003C\u002Fp>","When we first started doing Data Flow Diagrams at the start of the semester I thought they were the worst thing in the world. However, as I came to understand them more and start to think about more real-world business problems that I was encountering such as creating a website for my Dad or as […]","data-flow-diagrams",["Date","2019-04-19T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":251,"excerpt":391,"slug":394,"date":395,"modified":396,"readingTime":60,"acf":397,"tags":398,"author":18,"featuredMediaUrl":19,"featuredMedia":19},{"raw":392,"plain":393},"\u003Cp>During our Web Technologies practical lessons, we have to follow a set of instructions to create a website or simple script. The lecturer has hosted the notes for the unit on Firebase. I&#8217;d looked into Firebase before but couldn&#8217;t understand how to use it. However, when an extended task came up in lesson I gave [&hellip;]\u003C\u002Fp>","During our Web Technologies practical lessons, we have to follow a set of instructions to create a website or simple script. The lecturer has hosted the notes for the unit on Firebase. I’d looked into Firebase before but couldn’t understand how to use it. However, when an extended task came up in lesson I gave […]","firebase",["Date","2019-04-19T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":400,"excerpt":401,"slug":404,"date":405,"modified":406,"readingTime":60,"acf":407,"tags":408,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Angular, React, Vue, Node",{"raw":402,"plain":403},"\u003Cp>Whilst working on various projects this semester I&#8217;ve encountered the following technologies: Angular, React, Vue, and Node. I&#8217;ve experimented with them to some extent and found Node Package Manager quite useful. Initially, when I first heard about them I thought they were JavaScript Libraries like JQuery, however, they are far from it. Each technology is [&hellip;]\u003C\u002Fp>","Whilst working on various projects this semester I’ve encountered the following technologies: Angular, React, Vue, and Node. I’ve experimented with them to some extent and found Node Package Manager quite useful. Initially, when I first heard about them I thought they were JavaScript Libraries like JQuery, however, they are far from it. Each technology is […]","angular-react-vue-node",["Date","2019-04-19T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":410,"excerpt":411,"slug":414,"date":415,"modified":416,"readingTime":82,"acf":417,"tags":418,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"New Laptop, Deployment Manager, NAS and VPN",{"raw":412,"plain":413},"\u003Cp>I&#8217;d wanted to buy a new laptop for ages as mine was quite heavy and I wanted to take it to lectures, and store it in my bag but couldn&#8217;t. This meant I was looking for something quite light. I also wanted something powerful as I do a lot of media production and web development. [&hellip;]\u003C\u002Fp>","I’d wanted to buy a new laptop for ages as mine was quite heavy and I wanted to take it to lectures, and store it in my bag but couldn’t. This meant I was looking for something quite light. I also wanted something powerful as I do a lot of media production and web development. […]","new-laptop-deployment-manager-nas-and-vpn",["Date","2019-04-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":420,"excerpt":421,"slug":424,"date":425,"modified":426,"readingTime":60,"acf":427,"tags":428,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Git",{"raw":422,"plain":423},"\u003Cp>As part of my studies at Solent, we were introduced to using Git in our workflow. Git is useful as it means mistakes can be corrected by rolling back the code to a version that worked. I&#8217;d come across this before at Fluid Studios Ltd. where they were using Git Kraken, however, I&#8217;d never really [&hellip;]\u003C\u002Fp>","As part of my studies at Solent, we were introduced to using Git in our workflow. Git is useful as it means mistakes can be corrected by rolling back the code to a version that worked. I’d come across this before at Fluid Studios Ltd. where they were using Git Kraken, however, I’d never really […]","git",["Date","2019-04-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":430,"excerpt":431,"slug":434,"date":435,"modified":436,"readingTime":60,"acf":437,"tags":438,"author":18,"featuredMediaUrl":439,"featuredMedia":440},"Web Design Portfolio",{"raw":432,"plain":433},"\u003Cp>I&#8217;d been meaning to update my portfolio site for quite a while as I wasn&#8217;t really happy with the design. The long Christmas break gave me a chance to do just that. I was inspired by this template. In my lectures, we&#8217;d been learning about Figma and UX design. I wanted to use this redesign [&hellip;]\u003C\u002Fp>","I’d been meaning to update my portfolio site for quite a while as I wasn’t really happy with the design. The long Christmas break gave me a chance to do just that. I was inspired by this template. In my lectures, we’d been learning about Figma and UX design. I wanted to use this redesign […]","web-design-portfolio",["Date","2019-02-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F34a32b062918590e903c5210aa0d081d9960608cd1c70ece44100590aeafc4a6\u002F34a32b062918590e-Logo.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F34a32b062918590e903c5210aa0d081d9960608cd1c70ece44100590aeafc4a6\u002F34a32b062918590e-Logo.png",{"title":442,"excerpt":443,"slug":446,"date":447,"modified":448,"readingTime":60,"acf":449,"tags":450,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Transferring my hosting package from 1and1 IONOS to iPage",{"raw":444,"plain":445},"\u003Cp>I think transferring hosting provider was the single greatest nightmare I&#8217;ve had in my life. I bought a few domains with 1and1, hoping to get SSL certificates that were advertised, however you only get one SSL certificate per contract. I&#8217;d have to create multiple contracts for all my domains, and then would not be able [&hellip;]\u003C\u002Fp>","I think transferring hosting provider was the single greatest nightmare I’ve had in my life. I bought a few domains with 1and1, hoping to get SSL certificates that were advertised, however you only get one SSL certificate per contract. I’d have to create multiple contracts for all my domains, and then would not be able […]","transferring-my-hosting-package-from-1and1-ionos-to-ipage",["Date","2019-02-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":452,"excerpt":453,"slug":456,"date":457,"modified":458,"readingTime":60,"acf":459,"tags":460,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Website Updates: Portfolio and Memories – Joe Bailey Photography",{"raw":454,"plain":455},"\u003Cp>After creating my Web Design portfolio site and transferring my hosting package I was in the mood to do some web design. I&#8217;d been meaning to add a portfolio to my photography site for a long while. Whilst making the photography portfolio I created some cool code to create a gallery of images which you [&hellip;]\u003C\u002Fp>","After creating my Web Design portfolio site and transferring my hosting package I was in the mood to do some web design. I’d been meaning to add a portfolio to my photography site for a long while. Whilst making the photography portfolio I created some cool code to create a gallery of images which you […]","website-updates-portfolio-and-memories",["Date","2019-02-01T00:00:00.000Z"],["Date","2026-11-03T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":462,"excerpt":463,"slug":466,"date":467,"modified":468,"readingTime":60,"acf":469,"tags":470,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Don’t forget your future self – Dan Benham",{"raw":464,"plain":465},"\u003Cp>I attended a talk by Dan Benham, set up by the university, which I found really interesting. He works for Studio Republic in Winchester. He was tired of working for corporate clients and started an ethical business to combat this. His business helps charities and other ethical entities with their creative tasks. An interesting question [&hellip;]\u003C\u002Fp>","I attended a talk by Dan Benham, set up by the university, which I found really interesting. He works for Studio Republic in Winchester. He was tired of working for corporate clients and started an ethical business to combat this. His business helps charities and other ethical entities with their creative tasks. An interesting question […]","dont-forget-your-future-self-dan-benham",["Date","2019-01-31T00:00:00.000Z"],["Date","2026-11-03T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],[472,482,492,502,514,524,534,544,554,564],{"title":473,"excerpt":474,"slug":477,"date":478,"modified":479,"readingTime":82,"acf":480,"tags":481,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Web Components using PHP – Joe Bailey Photography",{"raw":475,"plain":476},"\u003Cp>In my Web Design and Development course, we touched on using web components and live style guides. This is the practice of having a set of components and styles that can be reused across your website. The advantage is that when something gets updated it rolls out across the whole site at the same time. [&hellip;]\u003C\u002Fp>","In my Web Design and Development course, we touched on using web components and live style guides. This is the practice of having a set of components and styles that can be reused across your website. The advantage is that when something gets updated it rolls out across the whole site at the same time. […]","web-components-using-php",["Date","2018-11-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":483,"excerpt":484,"slug":487,"date":488,"modified":489,"readingTime":60,"acf":490,"tags":491,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Wix Vs WordPress",{"raw":485,"plain":486},"\u003Cp>Now I&#8217;ve come across two instances of Wix in the past couple of months. Neither website was optimised for mobile. Wix has the option there, but it&#8217;s incredibly hard to use, you can change one thing and it will delete half the content on your site. The drag and drop editor is extremely slow, it&#8217;s [&hellip;]\u003C\u002Fp>","Now I’ve come across two instances of Wix in the past couple of months. Neither website was optimised for mobile. Wix has the option there, but it’s incredibly hard to use, you can change one thing and it will delete half the content on your site. The drag and drop editor is extremely slow, it’s […]","wix-vs-wordpress",["Date","2018-11-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":493,"excerpt":494,"slug":497,"date":498,"modified":499,"readingTime":71,"acf":500,"tags":501,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Flickr changes to free accounts – Joe Bailey Photography",{"raw":495,"plain":496},"\u003Cp>You might notice that my website uses Flickr to display most of the images. This is done by using an iframe of the Flickr slideshow. The reason I chose to use Flickr to display my images is that I didn&#8217;t have much experience coding at the time (I&#8217;m still not a code genius). It was [&hellip;]\u003C\u002Fp>","You might notice that my website uses Flickr to display most of the images. This is done by using an iframe of the Flickr slideshow. The reason I chose to use Flickr to display my images is that I didn’t have much experience coding at the time (I’m still not a code genius). It was […]","flickr-changes-to-free-accounts",["Date","2018-11-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":503,"excerpt":504,"slug":507,"date":508,"modified":509,"readingTime":60,"acf":510,"tags":511,"author":18,"featuredMediaUrl":512,"featuredMedia":513},"Logo design for a Web Developer",{"raw":505,"plain":506},"\u003Cp>My first project at university was to write a report on how I designed a set of logos to brand myself as a web developer. We had to include research, feedback and final designs. I got a C1 on this report as I found it quite hard being the first one I&#8217;ve done at university. [&hellip;]\u003C\u002Fp>","My first project at university was to write a report on how I designed a set of logos to brand myself as a web developer. We had to include research, feedback and final designs. I got a C1 on this report as I found it quite hard being the first one I’ve done at university. […]","logo-design-for-a-web-developer",["Date","2018-11-09T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fbfc46bfee4b29cd76ba47fce9df8298461166dcf1625803ae0fda5cf85803866\u002Fbfc46bfee4b29cd7-1Artboard-1joe.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fbfc46bfee4b29cd76ba47fce9df8298461166dcf1625803ae0fda5cf85803866\u002Fbfc46bfee4b29cd7-1Artboard-1joe.png",{"title":515,"excerpt":516,"slug":519,"date":520,"modified":521,"readingTime":60,"acf":522,"tags":523,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"rankingCoach",{"raw":517,"plain":518},"\u003Cp>I attended a workshop in Hotel Mercure Southampton Centre Dolphin on rankingCoach by Alasdair Stone. It was a very interesting event and we learnt about how to optimize website for search engines. We also learnt how to use tools such as Google My Business. I came away from the event with a lot of notes [&hellip;]\u003C\u002Fp>","I attended a workshop in Hotel Mercure Southampton Centre Dolphin on rankingCoach by Alasdair Stone. It was a very interesting event and we learnt about how to optimize website for search engines. We also learnt how to use tools such as Google My Business. I came away from the event with a lot of notes […]","rankingcoach",["Date","2018-11-08T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":525,"excerpt":526,"slug":529,"date":530,"modified":531,"readingTime":71,"acf":532,"tags":533,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Material Design",{"raw":527,"plain":528},"\u003Cp>“Make beautiful products, faster. Material is a design system – backed by open-source code – that helps teams build digital experiences” Material.io Material is a design language created by Google in 2014 for the Android platform. It has unified Android apps under a single design format. This has helped to give the Android platform a [&hellip;]\u003C\u002Fp>","“Make beautiful products, faster. Material is a design system – backed by open-source code – that helps teams build digital experiences” Material.io Material is a design language created by Google in 2014 for the Android platform. It has unified Android apps under a single design format. This has helped to give the Android platform a […]","material-design",["Date","2018-10-17T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":535,"excerpt":536,"slug":539,"date":540,"modified":541,"readingTime":60,"acf":542,"tags":543,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Barcamp Southampton",{"raw":537,"plain":538},"\u003Cp>I went to a Barcamp in Southampton, which consists of people giving talks on things they find interesting, with a heavy bias on technology. The normal talks last 45 minutes to an hour. They also have an opportunity to give lightning talks after lunch which last about 10 minutes and can be about anything. I [&hellip;]\u003C\u002Fp>","I went to a Barcamp in Southampton, which consists of people giving talks on things they find interesting, with a heavy bias on technology. The normal talks last 45 minutes to an hour. They also have an opportunity to give lightning talks after lunch which last about 10 minutes and can be about anything. I […]","barcamp-soton",["Date","2018-10-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":545,"excerpt":546,"slug":549,"date":550,"modified":551,"readingTime":71,"acf":552,"tags":553,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"CSS Grid",{"raw":547,"plain":548},"\u003Cp>&#8220;CSS Grid Layout is shaping up to be the layout tool we’ve always wanted on the web.&#8221; Stacy Kvernmo (September 19, 2016) In the early days of the web, developers laid things out using tables. Tables are only designed for tabular data and developers were splitting GIFs up to lay them out and create visually [&hellip;]\u003C\u002Fp>","“CSS Grid Layout is shaping up to be the layout tool we’ve always wanted on the web.” Stacy Kvernmo (September 19, 2016) In the early days of the web, developers laid things out using tables. Tables are only designed for tabular data and developers were splitting GIFs up to lay them out and create visually […]","css-grid",["Date","2018-10-04T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":555,"excerpt":556,"slug":559,"date":560,"modified":561,"readingTime":60,"acf":562,"tags":563,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Web Design and Development",{"raw":557,"plain":558},"\u003Cp>I&#8217;ve just started my first proper job in the Web Design and Development industry at Fluid Studios Ltd&nbsp;and it&#8217;s going really well. I&#8217;m also starting to get ready for university, the next big exciting chapter in my life.\u003C\u002Fp>","I’ve just started my first proper job in the Web Design and Development industry at Fluid Studios Ltd and it’s going really well. I’m also starting to get ready for university, the next big exciting chapter in my life.","web-design-and-development",["Date","2018-06-08T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":565,"excerpt":566,"slug":569,"date":570,"modified":571,"readingTime":60,"acf":572,"tags":575,"author":18,"featuredMediaUrl":576,"featuredMedia":577},"joebailey.xyz",{"raw":567,"plain":568},"\u003Cp>I&#8217;ve started creating a site to showcase my work as a web design professional. Once finished it will be live at joebailey.xyz I&#8217;m not really feeling it as much as my photography website, I don&#8217;t think the design flows that well, and it doesn&#8217;t really optimize for mobile all that well either. I think maybe [&hellip;]\u003C\u002Fp>","I’ve started creating a site to showcase my work as a web design professional. Once finished it will be live at joebailey.xyz I’m not really feeling it as much as my photography website, I don’t think the design flows that well, and it doesn’t really optimize for mobile all that well either. I think maybe […]","joebailey-xyz",["Date","2018-03-21T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":573},[266,293,574],"Netlify",[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe28b08c407668af2eb67e835a3986a145fd2c94feace17010d6a8d860d780278\u002Fe28b08c407668af2-Logo.jpg","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe28b08c407668af2eb67e835a3986a145fd2c94feace17010d6a8d860d780278\u002Fe28b08c407668af2-Logo.jpg",[579,589],{"title":580,"excerpt":581,"slug":584,"date":585,"modified":586,"readingTime":60,"acf":587,"tags":588,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"New Blog – Joe Bailey Photography",{"raw":582,"plain":583},"\u003Cp>I&#8217;ve finally started phase 3 of the redesign of my website. Phase one was to create it, learning lots of code along the way to prepare me for my University course, and also to give me the creative freedom that I hadn&#8217;t yet been able to achieve with various website builders. During phase 2 I [&hellip;]\u003C\u002Fp>","I’ve finally started phase 3 of the redesign of my website. Phase one was to create it, learning lots of code along the way to prepare me for my University course, and also to give me the creative freedom that I hadn’t yet been able to achieve with various website builders. During phase 2 I […]","new-blog",["Date","2018-03-21T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":590,"excerpt":591,"slug":594,"date":595,"modified":596,"readingTime":60,"acf":597,"tags":598,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Welcome – Joe Bailey Photography",{"raw":592,"plain":593},"\u003Cp>Hello everyone, Welcome to my new website. Sorry for the delay, it&#8217;s been a year in the making and there&#8217;s still much to do, like implement a store and add my backlog of images to the gallery. If you encounter any problems whilst browsing, please don&#8217;t hesitate to contact me, and I&#8217;ll see what I [&hellip;]\u003C\u002Fp>","Hello everyone, Welcome to my new website. Sorry for the delay, it’s been a year in the making and there’s still much to do, like implement a store and add my backlog of images to the gallery. If you encounter any problems whilst browsing, please don’t hesitate to contact me, and I’ll see what I […]","welcome",["Date","2018-01-20T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],1793975253032]