<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/assets/rss.xsl" type="text/xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tim Rutte&apos;s blog</title><description>Articles on AWS, backend architecture and AI in production. From projects, not from slides.</description><link>https://timrutte.de/</link><language>en</language><atom:link href="https://timrutte.de/en/rss.xml" rel="self" type="application/rss+xml"/><item><title>Eight steps, not a prompt: how I work with coding agents</title><link>https://timrutte.de/en/blog/coding-agents-eight-steps/</link><guid isPermaLink="true">https://timrutte.de/en/blog/coding-agents-eight-steps/</guid><description>The agent works in one of eight steps. How specification, architecture rules, CI and review turn speed into software rather than just more code.</description><pubDate>Sun, 11 Oct 2026 12:00:00 GMT</pubDate></item><item><title>Taking over a Go project: the first week</title><link>https://timrutte.de/en/blog/taking-over-a-go-project/</link><guid isPermaLink="true">https://timrutte.de/en/blog/taking-over-a-go-project/</guid><description>Go code tells you almost everything about itself, except whether it runs. What I check in the first week: operation, build, reachable vulnerabilities, load.</description><pubDate>Wed, 30 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Is your code too old for coding agents?</title><link>https://timrutte.de/en/blog/code-too-old-for-coding-agents/</link><guid isPermaLink="true">https://timrutte.de/en/blog/code-too-old-for-coding-agents/</guid><description>Whether a coding agent works safely in a codebase is not decided by its age but by whether a command can say no. Four questions that settle it.</description><pubDate>Tue, 29 Sep 2026 12:00:00 GMT</pubDate></item><item><title>PHP 8.2 ends on 31 December: what to do now</title><link>https://timrutte.de/en/blog/php-8-2-end-of-life/</link><guid isPermaLink="true">https://timrutte.de/en/blog/php-8-2-end-of-life/</guid><description>PHP 8.2 gets no more security updates from January. Who is affected, which target version is worth it and what the move from 8.2 costs.</description><pubDate>Tue, 29 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Terraform or AWS CDK? How I choose infrastructure as code</title><link>https://timrutte.de/en/blog/terraform-or-aws-cdk/</link><guid isPermaLink="true">https://timrutte.de/en/blog/terraform-or-aws-cdk/</guid><description>Terraform or AWS CDK? Why I usually describe AWS infrastructure with Terraform, and when CDK really earns its extra programming layer.</description><pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate></item><item><title>API Gateway or Application Load Balancer? What does a normal API on AWS need?</title><link>https://timrutte.de/en/blog/api-gateway-or-alb/</link><guid isPermaLink="true">https://timrutte.de/en/blog/api-gateway-or-alb/</guid><description>API Gateway or Application Load Balancer on AWS? When an ALB is enough, and when API Gateway actually justifies its extra layer.</description><pubDate>Thu, 24 Sep 2026 12:00:00 GMT</pubDate></item><item><title>ECS Fargate or Kubernetes: what does a normal application really need?</title><link>https://timrutte.de/en/blog/ecs-fargate-or-kubernetes/</link><guid isPermaLink="true">https://timrutte.de/en/blog/ecs-fargate-or-kubernetes/</guid><description>ECS Fargate or Kubernetes on AWS? Why I start normal applications on Fargate, and at what point Kubernetes actually pays back its overhead.</description><pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate></item><item><title>REST or gRPC for backend services?</title><link>https://timrutte.de/en/blog/rest-or-grpc/</link><guid isPermaLink="true">https://timrutte.de/en/blog/rest-or-grpc/</guid><description>REST or gRPC? Why I decide public APIs differently from internal service communication, and which criteria actually matter.</description><pubDate>Wed, 23 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Synchronous or event-driven? When I really decouple backend services</title><link>https://timrutte.de/en/blog/synchronous-or-event-driven/</link><guid isPermaLink="true">https://timrutte.de/en/blog/synchronous-or-event-driven/</guid><description>Synchronous or event-driven? Why I do not decouple backend services by default, and when a call, a queue or an event is the right fit.</description><pubDate>Tue, 22 Sep 2026 12:00:00 GMT</pubDate></item><item><title>The strangler fig pattern in practice</title><link>https://timrutte.de/en/blog/strangler-fig-pattern-in-practice/</link><guid isPermaLink="true">https://timrutte.de/en/blog/strangler-fig-pattern-in-practice/</guid><description>The switch is an afternoon, the data is the project: cut by ownership, shadow runs, switching in steps, and the five places where it tears.</description><pubDate>Sun, 13 Sep 2026 12:00:00 GMT</pubDate></item><item><title>From monolith to microservices</title><link>https://timrutte.de/en/blog/monolith-to-microservices/</link><guid isPermaLink="true">https://timrutte.de/en/blog/monolith-to-microservices/</guid><description>Three of the four reasons for splitting are delivery problems. What a service costs, what a module already does, and the four cases where a service really is one.</description><pubDate>Sun, 13 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Does the legacy application belong on Kubernetes?</title><link>https://timrutte.de/en/blog/legacy-application-on-kubernetes/</link><guid isPermaLink="true">https://timrutte.de/en/blog/legacy-application-on-kubernetes/</guid><description>The groundwork costs weeks, swapping the platform costs days. Three conditions under which a cluster pays, and what sits in between.</description><pubDate>Sun, 13 Sep 2026 12:00:00 GMT</pubDate></item><item><title>NIS2 and the legacy estate</title><link>https://timrutte.de/en/blog/nis2-legacy-systems/</link><guid isPermaLink="true">https://timrutte.de/en/blog/nis2-legacy-systems/</guid><description>Four of the ten areas are a question of construction for a grown system, not of intent. The findings, the evidence, and the order that is worth the money.</description><pubDate>Sun, 13 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Getting source code and access back</title><link>https://timrutte.de/en/blog/getting-source-code-from-an-agency/</link><guid isPermaLink="true">https://timrutte.de/en/blog/getting-source-code-from-an-agency/</guid><description>An archive is not software. What belongs on the list, in which order to ask for it, what to do on day one afterwards, and what helps when it stalls.</description><pubDate>Sun, 13 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Forty-four articles, five sentences that stayed</title><link>https://timrutte.de/en/blog/legacy-modernization-five-sentences/</link><guid isPermaLink="true">https://timrutte.de/en/blog/legacy-modernization-five-sentences/</guid><description>Five sentences that ran through forty-four articles, two assessments that shifted, and four entry points depending on your situation.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Rector in a legacy project</title><link>https://timrutte.de/en/blog/rector-in-a-legacy-project/</link><guid isPermaLink="true">https://timrutte.de/en/blog/rector-in-a-legacy-project/</guid><description>One rule set, one directory, one pull request: why the first attempt fails, which sets are mechanics and which are opinion, and how to review four hundred files.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>The handover day</title><link>https://timrutte.de/en/blog/handing-over-a-software-project/</link><guid isPermaLink="true">https://timrutte.de/en/blog/handing-over-a-software-project/</guid><description>A handover is a state, not an appointment. The one test that says anything, the access inventory before it, and a deadline instead of an open door.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Blue/green and canary without Kubernetes</title><link>https://timrutte.de/en/blog/blue-green-canary-without-kubernetes/</link><guid isPermaLink="true">https://timrutte.de/en/blog/blue-green-canary-without-kubernetes/</guid><description>Two machines and a switch are enough. The condition sits in the database, not the tooling, and without an abort rule a canary is just a slower release.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Retrofitting multi-tenancy</title><link>https://timrutte.de/en/blog/retrofitting-multi-tenancy/</link><guid isPermaLink="true">https://timrutte.de/en/blog/retrofitting-multi-tenancy/</guid><description>Three models and what they suit, the filter one level down, the test that finds leaks, and the half of the effort that is not in the database.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>What a modernization costs</title><link>https://timrutte.de/en/blog/what-does-a-legacy-modernization-cost/</link><guid isPermaLink="true">https://timrutte.de/en/blog/what-does-a-legacy-modernization-cost/</guid><description>The price is not driven by the amount of code but by five quantities you can establish in a week. Plus the items missing from every quote.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Removing features nobody uses any more</title><link>https://timrutte.de/en/blog/removing-unused-features/</link><guid isPermaLink="true">https://timrutte.de/en/blog/removing-unused-features/</guid><description>Measure instead of guessing, set the waiting period by the rhythm of the thing, and know what goes with it. Half-deleted is worse than not deleted.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>An end-of-life calendar for the whole stack</title><link>https://timrutte.de/en/blog/end-of-life-calendar-for-a-stack/</link><guid isPermaLink="true">https://timrutte.de/en/blog/end-of-life-calendar-for-a-stack/</guid><description>What carries an expiry date, how to build the list in a day, why end of life minus lead time is the only number that counts, and the sentence that gets the budget.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>The distributed monolith</title><link>https://timrutte.de/en/blog/distributed-monolith/</link><guid isPermaLink="true">https://timrutte.de/en/blog/distributed-monolith/</guid><description>Five sentences to diagnose it, why the cuts follow the nouns, what helps immediately without a rebuild, and why merging back is not a step backwards.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Cleaning up IAM in a grown AWS account</title><link>https://timrutte.de/en/blog/cleaning-up-iam-aws-account/</link><guid isPermaLink="true">https://timrutte.de/en/blog/cleaning-up-iam-aws-account/</guid><description>See first, then the keys, then the permissions: credential report and last-accessed data, OIDC instead of key pairs, one boundary instead of many rules.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Test data from production</title><link>https://timrutte.de/en/blog/test-data-from-production/</link><guid isPermaLink="true">https://timrutte.de/en/blog/test-data-from-production/</guid><description>Not the dump but the shaped slice: pick an anchor, find the silent references, mask deterministically, and close the outbound paths in the environment.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>A coding agent in a legacy codebase</title><link>https://timrutte.de/en/blog/coding-agent-in-a-legacy-codebase/</link><guid isPermaLink="true">https://timrutte.de/en/blog/coding-agent-in-a-legacy-codebase/</guid><description>What an agent is good for in legacy code, where it predictably fails, and the precondition without which it multiplies risk rather than speed.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Introducing OpenTelemetry in PHP and Go</title><link>https://timrutte.de/en/blog/introducing-opentelemetry-php-go/</link><guid isPermaLink="true">https://timrutte.de/en/blog/introducing-opentelemetry-php-go/</guid><description>Traces first, one path instead of all: the PHP export quirk, the context in Go, the seam across the queue, and what drives the invoice.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>The cache as a debt</title><link>https://timrutte.de/en/blog/cache-invalidation-legacy-system/</link><guid isPermaLink="true">https://timrutte.de/en/blog/cache-invalidation-legacy-system/</guid><description>Three kinds of cache, why an expiry time usually wins, what goes wrong with cached permissions, and how the debt gets paid back.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Modernizing a server-rendered front end without an SPA</title><link>https://timrutte.de/en/blog/modernizing-a-frontend-without-a-spa/</link><guid isPermaLink="true">https://timrutte.de/en/blog/modernizing-a-frontend-without-a-spa/</guid><description>Partial updates instead of a framework switch: the three problems that actually annoy users, twenty lines of JavaScript, and where this route ends.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Twelve weeks of modernization: a realistic plan</title><link>https://timrutte.de/en/blog/modernization-in-twelve-weeks/</link><guid isPermaLink="true">https://timrutte.de/en/blog/modernization-in-twelve-weeks/</guid><description>A shape that fits a quarter: six blocks, a result after each, a decision at the end, and the place where every plan tears.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Backups nobody has ever restored</title><link>https://timrutte.de/en/blog/testing-backup-restores/</link><guid isPermaLink="true">https://timrutte.de/en/blog/testing-backup-restores/</guid><description>Three ways backups fail silently, what a rehearsal actually measures, how it runs, and what rhythm can be sustained.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Configuration and secrets for Go services</title><link>https://timrutte.de/en/blog/configuration-and-secrets-in-go/</link><guid isPermaLink="true">https://timrutte.de/en/blog/configuration-and-secrets-in-go/</guid><description>Three layers with three origins, a start that fails on missing values, secrets without environment variables, and rotation without a restart.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Ten holes that sit in every old PHP system</title><link>https://timrutte.de/en/blog/security-holes-in-old-php-code/</link><guid isPermaLink="true">https://timrutte.de/en/blog/security-holes-in-old-php-code/</guid><description>The ten holes I find most often in grown PHP systems, the command that finds each one, and an order sorted by risk rather than by effort.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Putting an API in front of the monolith</title><link>https://timrutte.de/en/blog/api-in-front-of-a-monolith/</link><guid isPermaLink="true">https://timrutte.de/en/blog/api-in-front-of-a-monolith/</guid><description>Why the interface comes before the new front end, where it gets cut, how authentication is solved, and what the layer must not do.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>MySQL 5.7 to 8.0: what breaks in the move</title><link>https://timrutte.de/en/blog/mysql-5-7-to-8-0-migration/</link><guid isPermaLink="true">https://timrutte.de/en/blog/mysql-5-7-to-8-0-migration/</guid><description>Four classes of breakage, two of which stay silent, how to find them in advance, and what the managed service additionally does differently.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Introducing PHPStan into legacy code step by step</title><link>https://timrutte.de/en/blog/introducing-phpstan-into-legacy-code/</link><guid isPermaLink="true">https://timrutte.de/en/blog/introducing-phpstan-into-legacy-code/</guid><description>Eight thousand messages become zero in a day: the baseline, what actually gets found at which level, and where further levels deliver nothing.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Modernizing with an external freelancer</title><link>https://timrutte.de/en/blog/modernizing-with-an-external-freelancer/</link><guid isPermaLink="true">https://timrutte.de/en/blog/modernizing-with-an-external-freelancer/</guid><description>Why the team often changes nothing after the project, four testable criteria for handover readiness, and the role split that shifts over time.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>A PHP monolith on ECS Fargate</title><link>https://timrutte.de/en/blog/php-monolith-on-ecs-fargate/</link><guid isPermaLink="true">https://timrutte.de/en/blog/php-monolith-on-ecs-fargate/</guid><description>Containers without cluster administration: what belongs in the image, how configuration and secrets are separated, and what the health check has to check.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>From cron jobs to queues</title><link>https://timrutte.de/en/blog/replacing-cron-jobs-with-a-queue/</link><guid isPermaLink="true">https://timrutte.de/en/blog/replacing-cron-jobs-with-a-queue/</guid><description>When a schedule is no longer enough, how a job becomes a task with state, and why a job table is often enough instead of a dedicated queue.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Maintenance mode: running a legacy system safely</title><link>https://timrutte.de/en/blog/legacy-system-in-maintenance-mode/</link><guid isPermaLink="true">https://timrutte.de/en/blog/legacy-system-in-maintenance-mode/</guid><description>Not modernizing does not mean doing nothing. Five things that keep running, three that stop, and the two facts without which it is neglect.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Learning Go as a PHP developer: five wrong assumptions</title><link>https://timrutte.de/en/blog/learning-go-as-a-php-developer/</link><guid isPermaLink="true">https://timrutte.de/en/blog/learning-go-as-a-php-developer/</guid><description>Five places where Go means something different from what it looks like: errors, concurrency, packages, interfaces and the missing framework.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Shopware 5 plugins in the migration to 6</title><link>https://timrutte.de/en/blog/shopware-5-plugins-migration/</link><guid isPermaLink="true">https://timrutte.de/en/blog/shopware-5-plugins-migration/</guid><description>The cost driver is not the data, it is the plugins. Three lists instead of one, four categories with four answers, and the order that pays off.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Dual write and backfill: where migrations really tear</title><link>https://timrutte.de/en/blog/dual-write-and-backfill/</link><guid isPermaLink="true">https://timrutte.de/en/blog/dual-write-and-backfill/</guid><description>The five phases of a data migration on a running system, the code for the trickiest one, and the four places where it tears in practice.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Knowledge in one person is an architecture problem</title><link>https://timrutte.de/en/blog/developer-knowledge-monopoly/</link><guid isPermaLink="true">https://timrutte.de/en/blog/developer-knowledge-monopoly/</guid><description>Knowledge does not pile up because somebody hoards it but because the system forces it. Five properties, three useless measures, and what works instead.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Terraform drift: when console and code diverge</title><link>https://timrutte.de/en/blog/detecting-terraform-drift/</link><guid isPermaLink="true">https://timrutte.de/en/blog/detecting-terraform-drift/</guid><description>Drift is not an exception in grown environments. How to make it visible, the three possible answers, and where codification stops.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Laravel upgrades: where the pitfalls differ</title><link>https://timrutte.de/en/blog/laravel-upgrade-pitfalls/</link><guid isPermaLink="true">https://timrutte.de/en/blog/laravel-upgrade-pitfalls/</guid><description>Why the tools from a Symfony upgrade do not bite here, and four places where Laravel upgrades have pitfalls of their own.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Building an anti-corruption layer between Go and PHP</title><link>https://timrutte.de/en/blog/building-an-anti-corruption-layer/</link><guid isPermaLink="true">https://timrutte.de/en/blog/building-an-anti-corruption-layer/</guid><description>So the old data model does not travel into the new service: where the layer sits, what it translates, what it handles alongside, and when it goes.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Three measurements before you refactor a single line</title><link>https://timrutte.de/en/blog/baseline-before-refactoring/</link><guid isPermaLink="true">https://timrutte.de/en/blog/baseline-before-refactoring/</guid><description>Which three measurements have to exist before the first rebuild, how to get them without specialist tooling, and why the average is the wrong number.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Composer as archaeology</title><link>https://timrutte.de/en/blog/reconstructing-composer-dependencies/</link><guid isPermaLink="true">https://timrutte.de/en/blog/reconstructing-composer-dependencies/</guid><description>No lock file, vendor in the repository, patched packages: how to reconstruct the dependency tree of an old PHP project before raising it.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Sessions, uploads, state: three chains to one server</title><link>https://timrutte.de/en/blog/making-a-php-application-stateless/</link><guid isPermaLink="true">https://timrutte.de/en/blog/making-a-php-application-stateless/</guid><description>What stops an application running on more than one machine: sessions, uploaded files and state inside the process, and how to undo those chains.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Feature flags in a monolith without framework support</title><link>https://timrutte.de/en/blog/feature-flags-in-a-monolith/</link><guid isPermaLink="true">https://timrutte.de/en/blog/feature-flags-in-a-monolith/</guid><description>An implementation that stands up in a day: table, switch class, stable assignment. Where the switch sits, how it fits the database, and how it disappears again.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Lift and shift or replatforming</title><link>https://timrutte.de/en/blog/lift-and-shift-or-replatforming/</link><guid isPermaLink="true">https://timrutte.de/en/blog/lift-and-shift-or-replatforming/</guid><description>Moving and rebuilding are two projects. What changes even in a pure move, when replatforming pays off, and why the first bill goes up.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Which service to pull out of the monolith first</title><link>https://timrutte.de/en/blog/first-service-out-of-the-monolith/</link><guid isPermaLink="true">https://timrutte.de/en/blog/first-service-out-of-the-monolith/</guid><description>The first cut decides whether there is a second. Four criteria, three candidates that almost always fit, and three places you never touch first.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>The business case for a modernization</title><link>https://timrutte.de/en/blog/business-case-for-modernization/</link><guid isPermaLink="true">https://timrutte.de/en/blog/business-case-for-modernization/</guid><description>Four kinds of cost you can put a number on, lead time as a measurement instead of an estimate, a risk table with expected values, and the one slide.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Working through Symfony deprecations without drowning in the log</title><link>https://timrutte.de/en/blog/working-through-symfony-deprecations/</link><guid isPermaLink="true">https://timrutte.de/en/blog/working-through-symfony-deprecations/</guid><description>Turning twelve thousand messages into an order of work: three kinds of deprecation, the bottom-up route, and the rebuilds that never announce themselves.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>The real legacy is your database schema</title><link>https://timrutte.de/en/blog/legacy-database-schema/</link><guid isPermaLink="true">https://timrutte.de/en/blog/legacy-database-schema/</guid><description>The schema outlives every modernization of the code. The four legacy traits that are almost always there, what to measure first, and in what order to change.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>When deployment still runs over FTP</title><link>https://timrutte.de/en/blog/replacing-ftp-deployment/</link><guid isPermaLink="true">https://timrutte.de/en/blog/replacing-ftp-deployment/</guid><description>From &quot;somebody uploads it&quot; to a rollout with a way back: artefact, atomic switch, rollback, and where the database draws the line.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Testing legacy code when there are no tests</title><link>https://timrutte.de/en/blog/testing-legacy-code-without-tests/</link><guid isPermaLink="true">https://timrutte.de/en/blog/testing-legacy-code-without-tests/</guid><description>How to pin down the behaviour of a legacy system before you change it: characterization tests, golden master, seams, and when to stop.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Technical due diligence: assessing a legacy system in five days</title><link>https://timrutte.de/en/blog/technical-due-diligence-legacy-system/</link><guid isPermaLink="true">https://timrutte.de/en/blog/technical-due-diligence-legacy-system/</guid><description>How I assess a legacy system in five days before somebody buys or inherits it: the order of work, the commands, and what ends up in the report.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>When modernization is the wrong answer</title><link>https://timrutte.de/en/blog/when-modernization-is-the-wrong-answer/</link><guid isPermaLink="true">https://timrutte.de/en/blog/when-modernization-is-the-wrong-answer/</guid><description>Modernization is not always the right answer to a legacy system. When freezing, standard software or retirement is the better call, and how to tell.</description><pubDate>Sat, 12 Sep 2026 12:00:00 GMT</pubDate></item><item><title>Your developer is gone. The first week decides what it costs.</title><link>https://timrutte.de/en/blog/developer-gone-first-week/</link><guid isPermaLink="true">https://timrutte.de/en/blog/developer-gone-first-week/</guid><description>When the developer of a running system is gone, the first week decides the cost. What to secure before touching the code, in the right order.</description><pubDate>Fri, 11 Sep 2026 12:00:00 GMT</pubDate></item><item><title>German e-invoicing mandate 2027: your 2026 revenue decides</title><link>https://timrutte.de/en/blog/german-e-invoicing-mandate-2027/</link><guid isPermaLink="true">https://timrutte.de/en/blog/german-e-invoicing-mandate-2027/</guid><description>Whether you must issue e-invoices from January 2027 depends on your 2026 revenue. What counts, what is exempt, and why receiving them is not enough.</description><pubDate>Wed, 09 Sep 2026 12:00:00 GMT</pubDate></item><item><title>An agent is only as good as its context</title><link>https://timrutte.de/en/blog/second-brain-for-ai-agents/</link><guid isPermaLink="true">https://timrutte.de/en/blog/second-brain-for-ai-agents/</guid><description>How I moved my knowledge into a Git repository so agents can work with it. What held up after nine days, what did not, and what a team can take from it.</description><pubDate>Wed, 09 Sep 2026 12:00:00 GMT</pubDate></item><item><title>PHP 7.4 to PHP 8.4: what this upgrade really involves</title><link>https://timrutte.de/en/blog/php-7-4-to-php-8-4/</link><guid isPermaLink="true">https://timrutte.de/en/blog/php-7-4-to-php-8-4/</guid><description>PHP 7.4 has been without security updates since late 2022. What the jump to 8.4 involves: hard breaks, silent behaviour changes, real cost drivers.</description><pubDate>Sat, 29 Aug 2026 12:00:00 GMT</pubDate></item><item><title>Zend Framework 1 is still running. Support ended in 2016.</title><link>https://timrutte.de/en/blog/zend-framework-1-end-of-life/</link><guid isPermaLink="true">https://timrutte.de/en/blog/zend-framework-1-end-of-life/</guid><description>Zend Framework 1 has been without support since 2016 and still runs in production. What that means, what forks can do and the three ways out.</description><pubDate>Mon, 24 Aug 2026 12:00:00 GMT</pubDate></item><item><title>A year of FinOps on AWS: from 15,000 to 2,500 euros a month</title><link>https://timrutte.de/en/blog/aws-cost-reduction-case-report/</link><guid isPermaLink="true">https://timrutte.de/en/blog/aws-cost-reduction-case-report/</guid><description>Twelve months of FinOps across two AWS accounts: where the large amounts were and why commitments come last.</description><pubDate>Wed, 19 Aug 2026 12:00:00 GMT</pubDate></item><item><title>An AI system on a zero budget: six decisions, three mistakes</title><link>https://timrutte.de/en/blog/ai-in-production-on-zero-budget/</link><guid isPermaLink="true">https://timrutte.de/en/blog/ai-in-production-on-zero-budget/</guid><description>Six architectural decisions and three mistakes from an AI side project that must cost nothing. With real code and the places where it went wrong.</description><pubDate>Tue, 18 Aug 2026 12:00:00 GMT</pubDate></item><item><title>Bad architecture sends no alerts. It just keeps costing.</title><link>https://timrutte.de/en/blog/finops-aws-hidden-architecture-costs/</link><guid isPermaLink="true">https://timrutte.de/en/blog/finops-aws-hidden-architecture-costs/</guid><description>Where four- and five-figure amounts quietly disappear in grown AWS setups, and how to get them back without changing a single line of code.</description><pubDate>Thu, 11 Jun 2026 12:00:00 GMT</pubDate></item><item><title>When AWS loses a region: what actually matters when it gets serious</title><link>https://timrutte.de/en/blog/aws-region-outage-multi-region/</link><guid isPermaLink="true">https://timrutte.de/en/blog/aws-region-outage-multi-region/</guid><description>What actually matters when an AWS region goes down: multi-region strategies, realistic failover concepts and the costs nobody plans for.</description><pubDate>Thu, 09 Apr 2026 12:00:00 GMT</pubDate></item><item><title>Agentic coding with spec-driven development: why your AI agent needs structure before it writes code</title><link>https://timrutte.de/en/blog/agentic-coding-spec-driven-development/</link><guid isPermaLink="true">https://timrutte.de/en/blog/agentic-coding-spec-driven-development/</guid><description>Why your AI agent needs structure before it writes code. Spec-driven development as a method for predictable, consistent quality with AI tools.</description><pubDate>Mon, 30 Mar 2026 12:00:00 GMT</pubDate></item><item><title>Go in a PHP world: adding high-performance services without rebuilding everything</title><link>https://timrutte.de/en/blog/golang-in-a-php-world/</link><guid isPermaLink="true">https://timrutte.de/en/blog/golang-in-a-php-world/</guid><description>How I add new high-performance Go services to existing PHP systems without rebuilding everything. Strangler fig in practice instead of a big-bang rewrite.</description><pubDate>Tue, 03 Feb 2026 12:00:00 GMT</pubDate></item><item><title>Why full rewrites almost always fail</title><link>https://timrutte.de/en/blog/why-full-rewrites-fail/</link><guid isPermaLink="true">https://timrutte.de/en/blog/why-full-rewrites-fail/</guid><description>Rewrites fail, and so does standing still. Why the complete rebuild almost never works and how incremental modernization delivers measurable results.</description><pubDate>Sun, 11 Jan 2026 12:00:00 GMT</pubDate></item><item><title>From Sphinx to Manticore Search: a migration about latency, relevance and operational discipline</title><link>https://timrutte.de/en/blog/from-sphinx-to-manticore-search/</link><guid isPermaLink="true">https://timrutte.de/en/blog/from-sphinx-to-manticore-search/</guid><description>A search migration from Sphinx to Manticore about latency, relevance and operational discipline. From 5 seconds to under 100 ms in practice.</description><pubDate>Thu, 10 Jul 2025 12:00:00 GMT</pubDate></item><item><title>Technical debt as business risk, and why nobody listens until it is too late</title><link>https://timrutte.de/en/blog/technical-debt-as-business-risk/</link><guid isPermaLink="true">https://timrutte.de/en/blog/technical-debt-as-business-risk/</guid><description>Technical debt is not a developer problem. It is a business risk, and it grows quietly until it becomes visible exactly when there is no room for it.</description><pubDate>Thu, 03 Apr 2025 12:00:00 GMT</pubDate></item></channel></rss>