octyn-site
octyn.co is this site, and it is in the project list for the same reason everything else is. Every project is a typed record where the date on a number is mandatory, so a gap shows as a gap instead of being quietly left out. Next.js on Coolify, deployed by pushing to main. Shipping since 2026-07-06.
octyn-site in use


Next.js on Coolify, warm-dark ledger metaphor, JSON-fed PoW receipts. Recursion is the joke.
This is OCTYN's own site. It is in the project list for the same reason everything else is, and the recursion is deliberate.
1. The situation
Planned 2026-07-04 and shipping by 2026-07-06. Three products were already live on their own domains and none of them had a parent. A prospect who took a call, or landed from cold outreach, had nowhere to check that OCTYN existed as a firm rather than as a person with side projects.
2. Why it was hard
Not technically. A portfolio site for a two-person firm is a weekend. It is also trivially easy to disbelieve, because every number on it is self-reported and the reader knows it. So the constraint was structural: make the claims falsifiable. A page saying "12,000 interactions" with no date and no source is indistinguishable from a page that made the number up, and an experienced buyer reads it as exactly that.
3. What was built
Next.js on Coolify, deployed by pushing to the main branch, which triggers a webhook, a Nixpacks build and a rolling restart on OCTYN's own server behind Cloudflare. The same pattern runs every other OCTYN site, so the deploy path is one thing to know rather than four.
The important part is the data model, not the framework. Every project is a typed record in one file, and the metric type makes the date mandatory rather than optional. Where a real number does not exist, the slot carries an honest label with the same shape and the same date, so a gap is visible as a gap instead of being quietly omitted.
Live receipts come from a JSON feed emitted by the GitHub organisation: status, last deploy, uptime and commit activity. The site reads upstream first and falls back to local stub files, with an hour of revalidation between fetches.
4. What it does under load
Twenty projects on the lineup page. Ten of them hold a typed record in src/lib/projects.ts carrying either a dated metric or an honest label, as of 2026-07-06, and those are the ones that get a page of their own. The receipt feed revalidates hourly.
There is no published traffic figure and no published uptime percentage on the page. The uptime data is collected and the site can render it, but nothing is claimed in public yet, and until it is we would rather say so than round something up.
5. What happens when it breaks
The failure mode that matters here is not a page being down. It is a page showing a number that is wrong, because the consequence lands on every other claim OCTYN makes.
So the receipt path is upstream-first with a local fallback. If the GitHub feed is unavailable, the site serves the last known local payload rather than a zero, an error, or an empty space where a number used to be, and switches back on its own as soon as upstream responds. Payload shapes are pinned to a dated schema version, so a change upstream is a typed break at build time instead of a blank panel in production.
Deployment failure is contained by the platform: a build that does not compile never replaces the running container, so a broken commit leaves the live site untouched. Rollback is a revert and a push, the same path as any other deploy, so there is no separate emergency procedure to get wrong under pressure.
Cloudflare sits in front for DNS, proxy and certificates, and is also where the worst failure on this project came from, which is section 8.
6. Who maintains it, and what that costs in attention
Almost no code attention. The site has few dependencies and no database, and it has gone long stretches without needing a commit.
The real cost is editorial and it recurs. Every metric on the page has a date, which means every metric visibly ages. A number captured in July reads as a July number in December, and the only honest options are to refresh it or let it show its age. That is a deliberate cost, because the alternative is undated numbers that never grow stale since nobody can tell when they were true. In practice it is a periodic pass over one typed file, re-reading each number against its source. Minutes rather than hours, and skipping it is visible to anyone reading closely.
7. What changes when requirements change in six months
Configuration, no code. Projects, buckets, services and FAQ entries are typed data in one place. Adding a project, retiring one, or changing a metric is an edit to that file, and the navigation, counts and groupings derive from it rather than being maintained alongside it.
A code change, contained. New routes. Each project already carries a slug, so a case-study page per project and a sitemap generated from the same source is wiring rather than authoring. That was the plan from the start, and it is why the slug exists on a record that did not yet need one.
A code change, larger. Anything needing content edited by someone who does not open an editor. The data is typed TypeScript, which gives compile-time guarantees a content system cannot, at the cost of a deploy for a typo.
A rebuild, only if the site has to be edited by people other than the team that deploys it. We made that trade knowingly, toward correctness over convenience, because a wrong number here is more expensive than a slow one.
8. What we would do differently
Check what the edge is serving, not what the code says. The repository's robots policy allows every crawler. The live response did not, because a managed block list at the CDN was prepended ahead of the origin, so retrieval crawlers were turned away from a site whose entire job is to be found by people checking whether OCTYN is real. Nothing in the codebase would ever have revealed it.
Server-render the work that is the evidence. The portfolio at /work is still a static file that assembles its own markup in the browser, so the one page carrying the proof is the page a crawler cannot read: fetch it and the project names come back as unresolved template expressions. A server-rendered replacement was built and then reverted, because it was worse than the page it replaced and the design is the right one. The fix is to pre-render this design rather than to swap it for another, and it has not been done yet. Until it is, the long-form write-ups under /casestudies are the crawlable version of the same evidence.
Measure the site the way a stranger would. The audit that found all of this took an afternoon, and should have been run the week the site went live rather than after a buyer said the quiet part out loud.
Want something like octyn-site for your operation?
Book a call →