Chris Kelechukwu Photography
Christian's own photography business, which predates BespokeForge and is still run to the same standard as client work.
Built for the moments worth keeping
Chris Kelechukwu Photography is my own brand, and it is built around something I love: documenting people at their happiest and crafting those moments into images they keep for life. Weddings, portraits, beauty, the occasions worth remembering. The work is about authenticity and storytelling, telling your story in its truest form.
The site has two jobs: show the work at full visual quality, and turn a browser into a booked session. It had to feel warm and unhurried and lead with the photographs, so I built it from scratch, properly engineered underneath, to do exactly that and to stay fast and simple for me to run.
Brand-led, and editable without code
The site is WordPress on a lightweight Hello Elementor base, built with Elementor Pro so I can edit and grow it without touching code. It is organised around the journey: a hero-led home, dedicated Wedding, Beauty and Portrait pages, a portfolio of around ninety curated images with lightbox galleries, a clear booking path, and a Musings blog for editorial reach. Rank Math handles the SEO, schema, and sitemaps, so search engines read it as a local Abuja photography business.
A hardened, self-managed stack
I run it on my own Linux server, not shared hosting, so I control the whole performance and security path. It sits behind Cloudflare with HTTP/3, served by nginx with a Varnish full-page cache, and PHP, Redis and MariaDB underneath. The origin only accepts traffic from Cloudflare, SSH is key-only with fail2ban, and a web application firewall plus two-factor authentication harden the application. Off-site backups and server-side snapshots keep it recoverable.
It runs and captures work on its own
Every photo I upload is capped to 1200px and converted to WebP on the server with Imagick automatically, no external service or per-image cost, so I drop in a full-resolution shot and the site serves a fast, web-ready version. Thirty-seven Elementor Pro forms each save the enquiry to the database and email the studio, so nothing is lost. The page cache purges itself on publish, the CSS and JavaScript are aggregated automatically, and an n8n engine runs on the same box, ready to route enquiries into a CRM or calendar later.
An owned enquiry pipeline
The site is also a data system. MariaDB and Redis run the content and caching, the portfolio is structured in SCF, and the media library is 706 files at 30.6 MB, of which 654 are optimised WebP totalling 27.3 MB. The real asset is the enquiry pipeline: close to two hundred client enquiries captured so far as first-party data, every one also delivered to the inbox, owned outright and exportable into any future CRM.
Fast under a heavy portfolio
An image-heavy portfolio is the hardest kind of site to keep fast, so I tuned the delivery end to end: made the full-page cache actually cache, preloaded the hero at high priority, re-encoded every photo to WebP in place, and streamlined the CSS and JavaScript.
WebP rather than AVIF is worth a note. AVIF makes the smaller file, and smaller is supposed to be faster, but it costs a processor considerably more to decode, and once the processor is the bottleneck rather than the connection, that decode cost can outweigh the few kilobytes it saves on a hero image. Fewer bytes is not automatically an earlier paint. I did not choose WebP here for that reason, I simply never had cause to move off it, which is one of those times the boring choice quietly turns out to have been the right one.
I measured the result again rather than quote what I remembered. On desktop, PageSpeed Insights scores the site 100, with first paint at 337 ms, Largest Contentful Paint at 762 ms, and a layout shift of 0.002, which is effectively nothing. The figure I am most pleased with is the server response: 2 to 3 ms. That is not clever PHP, it is the Varnish cache in front of the site handing over a page that was already built. The homepage is about 1 MB across 10 to 12 images, the hero itself 78 KB and the heaviest of them a 126 KB WebP further down the page, and the whole library on disk is 30.6 MB with no visible loss of quality.
These are finishing figures rather than before and afters, deliberately. I can point at a PageSpeed run and a directory listing from the day I wrote this, I cannot evidence what the site was doing before I touched it, and a number nobody can check is worth less than no number at all. They are desktop figures.
See it in production.
By the numbers.
Guides from this engagement.
The technical detail behind this work, written up in full.
Start with a conversation.
A short conversation first, to work out which of the two routes you are on and whether this is a problem I can solve. The audit is the paid step that follows, and what it produces is yours whether or not anything comes after it.
Twenty-five minutes on Google Meet, and a straight answer either way.
- 01
You describe what you are running, in whatever words you use for it internally.
- 02
You get a straight answer on whether the audit is worth doing at all, including when it is not.