Sign in

Tom Elliott

@telliott.me
478 followers 1.4K following 1K posts

DevOps enthusiast. Posts bi-weekly on thefridaydeploy.substack.com, occasional public speaker.

PostsRepliesMedia
Tom Elliott @telliott.me · 17/04/2026
I recently hit the two month mark at @modal-labs.bsky.social and I’d love you to come join me! Hard to believe it’s just 8 weeks, we’re shipping so often, learning fast, and growing even faster. Plenty of brand-new, empty desks and interesting technical challenges. modal.com/company#care...
Entrance of the Modal office, showing the company logo and a "Welcome to Modal" signEmpty desks at the Modal office
000
Tom Elliott @telliott.me · 22/03/2026
A teachable moment for AI
Thank you for catching my mistake! It's important to use actual API features rather than making them up.
030
Tom Elliott @telliott.me · 06/01/2026
I write fairly regularly, but always feel like I don't read as much as I should. Looking back over the past week, I've read a bunch of articles, so why do I still feel like I'm behind the curve? Subscriptions. (thread follows)
A stack of books with an open book on top.
100
Tom Elliott @telliott.me · 31/12/2025
Someone had too much fun
A gingerbread man covered in fairy lights laying face down on the ground
000
Tom Elliott @telliott.me · 29/12/2025
Started on a just-for-fun project yesterday. Rendering all the buildings in NYC in 3D. opendata.cityofnewyork.us has a ton of great data sets, including this building data! Learned a ton about optimizing scenes. Had to get creative with reusing and grouping meshes. #buildinpublic
View of a 3D Map of NYC buildings, showing Manhattan as viewed from above south Brooklyn
141
Tom Elliott @telliott.me · 27/12/2025
Squirrel footprints on the scaffold! Magical.
Trail of small footprints in snow on a platform
010
Tom Elliott @telliott.me · 24/12/2025
My bones are so brittle, but I always drink plenty of…
Bottles of “malk”
000
Tom Elliott @telliott.me · 11/11/2025
Ok, I'm really starting to like this style. #buildinpublic
A screenshot of a web page in a pixel art form showing a set of connected cloud resources.
151
Tom Elliott @telliott.me · 11/11/2025
Took a detour last night to experiment with pixel art for icons. Watched some videos, got the Aesprite trial and threw together a few ideas. There's something really satisfying about the precision you can get at 32x32. Now to pay for the full version and build some UIs! #buildinpublic
031
Tom Elliott @telliott.me · 17/10/2025
Had more fun with the Ocuroot REPL this afternoon. I've added some prettier rendering to return values, with highlighting and a tree view for more complex structures. It even prints function docs for you! #buildinpublic
071
Tom Elliott @telliott.me · 14/10/2025
Well this is weird, Vemetric shows a spike in visits to ocuroot.com at about 6am. A bunch of different users each visiting a different docs page. I'm thinking either a scraper or someone with really good tracker blocking. @dominiksumer.com any tips on solving the mystery?
Graph from vemetric.com showing a spike at 6am.
110
Tom Elliott @telliott.me · 14/10/2025
Continuing the dependency tracking work, I had some fun yesterday putting together a function using Go's tooling to get a list of source files in a build. These can be recorded to Ocuroot's state each build to match against incoming commits. #buildinpublic #openstandup
Screenshot of a terminal running the Ocuroot REPL. A function call has been made to `files_in_go_build("./cmd/ocuroot")` resulting in output of a list of files.
031
Tom Elliott @telliott.me · 09/10/2025
Spent most of the day working on Friday's blog post, but treated myself to some CLI work in the afternoon. Polished my REPL a little with bubbletea from @charm.sh. Always a delight using these libraries and I discover something new every time. #openstandup #buildinpublic
041
Tom Elliott @telliott.me · 06/10/2025
Quick demo of a tool I've been working on to simulate cloud deployments with real-time visual updates. Follow along, and I'll be sharing hosted and open source versions soonish. #openstandup #buildinpublic
050
Tom Elliott @telliott.me · 01/10/2025
Updated the mock cloud UI to show dependencies as a graph. Line overlaps will need addressing, but for now highlighting will help clarify what's what. Also started the API so you can create accounts. Next up will be managing resources. #openstandup #buildinpublic
A set of cloud resources with connections. Services are shown having dependencies on object storage and databases.
040
Tom Elliott @telliott.me · 30/09/2025
Ocuroot demos have tended to be a little hard to follow, with several endpoints and UIs to jump between. So I'm working on a mock cloud interface to show resources being created/updated across multiple "accounts". Goal is to have an API and update the UI in realtime. #openstandup #buildinpublic
A simple UI showing a set of cloud resources in a staging and production environment. There are a mix of databases, services and object stores.
050
Tom Elliott @telliott.me · 29/09/2025
In the v0.3.14 release post for @ocuroot.com, I mentioned that CI integration isn't as simple as it could be - so that's been my focus since. Ocuroot can now perform work across multiple repos and commits in a single run, meaning less setup and faster time to stability. #openstandup #buildinpublic
132
Tom Elliott @telliott.me · 28/09/2025
Wifey made me a new espresso mug. Amazing how she got the volume just right!
010
Tom Elliott @telliott.me · 17/09/2025
Short and sweet update today! Added a little detail on the config being loaded to help with debugging. At a conference today, but keep an eye out for a new release tomorrow! github.com/ocuroot/ocur... #openstandup #buildinpublic
041
Tom Elliott @telliott.me · 16/09/2025
Cleaned up those annoying UI issues from yesterday and cut v0.3.13. See github.com/ocuroot/ocur... I don't want to stay on 13 too long (superstitious), so will make some more tweaks today to cut a new version ready to announce later this week. #openstandup #buildinpublic
032
Tom Elliott @telliott.me · 15/09/2025
Trying something new, a video open standup! Added a couple of new features to clear up some confusion in the quickstart, a dryrun flag and comprehensive mode. Still has a few improvements needed, that I'll work on today. #openstandup #buildinpublic
031
Tom Elliott @telliott.me · 08/09/2025
Big UX improvements to the @ocuroot.com CLI over the weekend. Work is now grouped by repo and config file so you know exactly what work was done. Also fixed an issue with deploys and teardowns appearing the same. Today I'll be simplifying the intent model. #openstandup #buildinpublic
Screenshot of the Ocuroot CLI showing indented grouping for a repo and config file.
030
Tom Elliott @telliott.me · 07/09/2025
I was watching Alien: Earth and something seemed oddly familiar...
The Ocuroot logo, a stylized eye with three "roots" at each edge, next to a screenshot from Alien: Earth with a creature that looks like an eye with tentacles.
000
Tom Elliott @telliott.me · 28/08/2025
Sitting down to day 2 of this year’s GopherCon. Some learnings from yesterday: - AI Agents don’t need to be individual services. Firing up some goroutines works great - I need to use Go’s tools more for profiling and linting, and they’re only going to get better - There’s a range keyword now
Stage at GopherCon lit up in blue, showing the 2025 logo
020
Tom Elliott @telliott.me · 25/08/2025
Here's where I'll be this week, who will I be seeing there? See replies because long...
A pair of glasses on top of a calendar, with January open.
100
Tom Elliott @telliott.me · 19/08/2025
Working from a new spot today. Felt like I needed to get out of the apartment more regularly.
A laptop on a small table in front of a tree covered in yellow lights.
020
Tom Elliott @telliott.me · 18/08/2025
Productive weekend! Added filesystem features to the SDK, added validation for various names and updated the function view for more readable inputs and outputs. Today I'll be building out some demo repos. #openstandup #buildinpublic
Screenshot from the Ocuroot UI showing a set of inputs and outputs. The outputs include a multi-line string rendered as preformatted text.
041
Tom Elliott @telliott.me · 14/08/2025
Spent an hour or so fiddling with Mermaid to draw an architecture diagram and realized I was trying to duplicate an HTML grid. So I did that instead. I want to replace the emojis, but found an icon set I like. Might have to fire up Figma and make my own. #openstandup #buildinpublic
021
Tom Elliott @telliott.me · 11/08/2025
I was cranking out the improvements over the weekend! The long ref headings on the state views are broken into "parent" links and short, descriptive header. There's a new retry feature for failed tasks, and you can see history of those jobs for each step in a release. #openstandup #buildinpublic
Screenshot of a release in the Ocuroot state view UI, showing a new heading layout.

"Release 0.3.7" is a full-sized heading, shown below "parent" links to the github.com/ocuroot/ocuroot repo and the "release.ocu.star" config file.A screenshot of a segment of the Ocuroot state view UI showing a call to the "release" function that failed twice and succeeded once. There are indicators for the failures and success in, order. Before the indicators are three dots to show there were previous additional runs not shown.
010
Tom Elliott @telliott.me · 06/08/2025
Continued working on the new example app, and wanted an easier way to test things, so I re-introduced the REPL feature from the prototype #openstandup #buildinpublic
Terminal screenshot showing `ocuroot repl release.ocu.star` being started, and the command `print(host.shell("ls",mute=True).stdout)` being run inside it.
020
Tom Elliott @telliott.me · 05/08/2025
Made a ton of progress on the state view yesterday and it's starting to feel much more navigable and informative. I even got some time in the evening to build up a new example app with a VPS. Today I'll be doing more polishing on both! #openstandup #buildinpublic
Split view showing inputs and outputs from a function called "_deploy" with inputs and outputs on the left and logs on the right.

The function and the broader work it is part of are both marked as successful.
010
Tom Elliott @telliott.me · 04/08/2025
Updated the view of child refs to show them in a tree, which is a little easier to navigate. This will only be a fallback for unhandled types, though. Also cleaned up the UI repo a bit. Today, I'll work on rendering more state types, like functions and environments. #openstandup #buildinpublic
Green text on black background. A tree view showing structure of a URI hierarchy, broken up based on the presence of a state file.
031
Tom Elliott @telliott.me · 02/08/2025
This is why I can’t vacuum right now. And I’m sticking to that story.
A cat curled up in a small cat bed next to a blue toy.
130
Tom Elliott @telliott.me · 01/08/2025
After last night's rain in NYC, this Waymo was forced into the open prematurely.
A Waymo-branded self-driving car parked on a side street in front of a tree.
000
Tom Elliott @telliott.me · 01/08/2025
Release statuses are now rendered as a pipeline view, similar for logs. The list of child refs should probably be customized based on the type as well, will look into that part today. #openstandup #buildinpublic
020
Tom Elliott @telliott.me · 28/07/2025
I was getting frustrated having to navigate state to find deployment outputs and missing inputs, so I added them to the TUI. Now I need to make the built-in version ids shorter 😅 #openstandup #buildinpublic
A terminal screenshot showing a deployment to staging with a tree of output names and their values
050
Tom Elliott @telliott.me · 28/07/2025
I'll be at two events this week, let me know if I'll be seeing you there! Tuesday evening is the Kubernetes NYC meetup by Plural lu.ma/axbw5s73?tk=... Thursday morning is the Brits in Tech coffee meet lu.ma/v8gs8acb?tk=...
020
Tom Elliott @telliott.me · 27/07/2025
Then playing with blur filters I accidentally created an eclipse effect. I need to do more of this recreational coding, very relaxing. codepen.io/theotherelli...
An image recreating an eclipse, with a blurred corona effect behind a black circle.
110
Tom Elliott @telliott.me · 27/07/2025
I promised myself I wouldn't do any work today, but I didn't say I wouldn't do any coding! So I had some fun learning HTML canvases and had a crack at recreating part of the UI from the 2012 Syndicate game. codepen.io/theotherelli...
An icon surrounded by a random circular graphic equalizer-type view.
000
Tom Elliott @telliott.me · 17/07/2025
This is the state of my dock recently. Have you settled on a favorite AI dev tool or are you like me and still hunting around? I'm hosting a roundtable on AI dev tool adoption tomorrow at 6pm ET, would love to hear your thoughts there: d2.gradual.us/events/d2-ro...
000
Tom Elliott @telliott.me · 30/06/2025
This scaffold outside our apartment is starting to look like Mario Kart.
A network of wooden walkways around apartment buildings, surrounded by trees.
010
Tom Elliott @telliott.me · 30/06/2025
Another busy weekend working on Ocuroot! The highlight: updating the terminal UI for a clear view of what's going on at each step. @charm.sh made it almost embarrassingly easy. I was even able to get it to switch between the summary and detailed logs on-demand. #openstandup #buildinpublic
150
Tom Elliott @telliott.me · 25/06/2025
One hour to go! At noon ET, I'll be appearing on the Scaling Tech Podcast to talk DevOps, CI/CD and supporting fast-growing engineering orgs. Join live with your questions: * LinkedIn: www.linkedin.com/events/73386... * YouTube: www.youtube.com/watch?v=Y38x...
Banner image for a Scaling Tech Podcast (from agility feat) event titled "Managing Deployments and DevOps at Scale".
Wednesday June 25, 2025 at 12:00 noon Eastern US.
010
Tom Elliott @telliott.me · 23/06/2025
After a couple quiet weeks, this is another packed one. Let me know if I'll be seeing you at any of these events! Full list in thread.
100
Tom Elliott @telliott.me · 19/06/2025
I've moved the Ocuroot binary builds over to the new SDK, kicking off a separate build function for each platform that can run in parallel or on separate machines. Big step up from previous SDK versions! Not pictured: unit tests and automatic version incrementing. #openstandup #buildinpublic
Code snippet in Starlark:


oses = ["linux", "darwin", "windows"]
arches = ["amd64", "arm64"]

def build(ctx):
    os = ctx.inputs.os
    arch = ctx.inputs.arch
    version = ctx.inputs.version

    # Build the binary for this platform
    output = "./.build/{os}-{arch}/ocuroot".format(os=os, arch=arch)
    host.shell("GOOS={os} GOARCH={arch} go build -o {output} ./cmd/ocuroot".format(os=os, arch=arch, output=output))
    
    # Upload to R2
    host.shell(
        "rclone copy {output} ocuroot_binaries:client-binaries/ocuroot/{version}/{os}-{arch}".format(
            os=os, 
            arch=arch, 
            output=output, 
            version=version,    
        )
    )

    # Output the URL for future use
    url = "https://downloads.ocuroot.com/ocuroot/{version}/{os}-{arch}/ocuroot".format(os=os, arch=arch, version=version)
    return done(outputs={"download_url": url})

phase(
    name="build",
    work=[
        call(
            build,
            name="build_{os}_{arch}".format(os=os, arch=arch),
            inputs={"os": os, "arch": arch, "version": ref("./call/increment_version#output/version")},
        )
        for os in oses
        for arch in arches
    ],
)
041
Tom Elliott @telliott.me · 18/06/2025
Simplified the declaration of release steps to make the config file read more like a top-to-bottom script. It's so much cleaner! There's probably space to simplify this even further, but for now I'm going to focus on setting up a "production" build to publish a client binary. #openstandup
Code screenshot:

ocuroot("0.3.0")

load("./tasks.ocu.star", "build", "up", "down")

envs = environments()
staging = [e for e in envs if e.attributes["type"] == "staging"]
prod = [e for e in envs if e.attributes["type"] == "prod"]

phase(
    name="build",
    work=[call(build, name="build")],
)

phase(
    name="staging",
    work=[
        deploy(
            up=up,
            down=down,
            environment=environment,
            inputs={
                "input1": ref("./call/build#output/output1"),
                "previous_count": ref("./@/deploy/{}#output/count".format(environment.name), default=0),
            },
        ) for environment in staging
    ],
)
010
Tom Elliott @telliott.me · 12/06/2025
This was fun! I expanded my tracing support to track the new release structure, roughly conforming to the semantic conventions for CICD. So you can point any run of a release at a collector and see where the time was spent. Just in time for a demo this afternoon. #openstandup #buildinpublic
Screenshot of a Jaeger trace showing the steps involved in a partial run of a release with Ocuroot.
161
Tom Elliott @telliott.me · 04/06/2025
I've struggled to find a nice way to give friendly names to releases. Brainstorming with a friend on Monday, we hit upon the obvious prior art. Tags in Git and Docker. Barely even took a half day to build in too 😄 Next up, testing some more complex dependencies. #openstandup
A screenshot of a terminal showing recommendations for approving next steps in a release using a release id and tag.
010
Tom Elliott @telliott.me · 02/06/2025
It's such a nice day we're going to have coding outside.
A blue sky seen looking up through trees, with sunlight from above.
020
Tom Elliott @telliott.me · 21/05/2025
Put basic of secret management in the local flow yesterday. Needs serious polish, but does the job of injecting secrets manually. Had fun writing concurrent code to provide the SDK with a secret store that blocked on the form. Gotta resist the temptation to put sleeps into unit tests! #openstandup
A form asking the user to provide a secret called "sc", or skip it entirely.
110