Ich habe Claude Code benutzt, um meine Full-Stack-App von Serverless auf Monolith zu migrieren
8 Monate Kampf mit Serverless-Infrastruktur, 5 Monate Stille, und ein 3-Wochen-Rewrite -- mit Git-Logs als Beweis.
Ich habe Claude Code benutzt, um meine Full-Stack-App von Serverless auf Monolith zu migrieren
8 Monate Kampf mit Serverless-Infrastruktur, 5 Monate Stille, und ein 3-Wochen-Rewrite — mit Git-Logs als Beweis.
Ich habe 8 Monate damit verbracht, gegen meine Infrastruktur auf SST (Serverless Stack) auf AWS zu kaempfen, musste zusehen, wie mein Projekt 5 Monate lang mit null Commits vor sich hin starb, und habe dann Claude Code genutzt, um das gesamte Backend von SST/TypeScript auf FastAPI/Python in 3 Wochen neu zu schreiben. 432 veraenderte Dateien. 24.422 Einfuegungen. 11.569 Loeschungen. Es war keine Magie, aber es hat veraendert, wie ich Software baue.
Dieser Beitrag setzt voraus, dass du schon mal eine Full-Stack-App gebaut oder gewartet hast und neugierig auf AI-gestuetzte Entwicklung bist. Claude-Code-Erfahrung ist nicht noetig.
Am 10. Maerz 2025 habe ich 6 Docker-bezogene Commits an einem einzigen Tag gemacht. Die Commit-Messages lesen sich wie ein Entwickler, der einen Kampf in Zeitlupe verliert: added docker, added docker, reverted docker file, fixed docker, fixed docker, fixed docker. Das war nicht mal der schlimmste Tag in dem Monat. Maerz 2025 hatte insgesamt 196 Commits, und die meisten davon waren Infrastruktur-Fixes. Ich baute eine Fotomosaik-App und verbrachte meine Tage mit dem Debugging von Container-Deployments.
Schnitt auf den 16. Februar 2026. Ich habe eine 4-Phasen-Datenmodell-Migration ausgeliefert, bei der eine monolithische Media-Tabelle in kontextspezifische EventMedia- und MosaicMedia-Tabellen aufgeteilt wurde — mit Abwaertskompatibilitaet, Design-Docs und Tests. Alles an einem Tag. Nicht weil ich ueber Nacht ein besserer Entwickler geworden bin. Die Architektur unter mir hatte sich veraendert, und ich hatte ein anderes Werkzeug in der Hand.
Wenn du jemals eine Architekturentscheidung frueh in einem Projekt getroffen hast, die du spaeter bereut hast, und die Kosten fuer ein Rewrite zu hoch schienen — das ist genau diese Geschichte. Diese Luecke zwischen “Ich weiss, dass das falsch ist” und “Ich kann es mir leisten, das zu fixen” ist der Ort, an dem Projekte sterben. Meins waere fast daran gestorben.
Vorab: Das hier ist keine Claude-Code-Werbung. Es ist ein ehrlicher Bericht darueber, was passiert ist, als ich auf AI-gestuetzte Entwicklung gesetzt habe, um mich aus einem Loch zu graben, das ich monatelang selbst geschaufelt hatte. Die Erfolge waren echt. Die Ecken und Kanten auch.
Warum Serverless (SST) richtig schien — und wann es das nicht mehr war
TessellAI ist ein Fotomosaik-Generator fuer Live-Events. Gaeste auf einer Hochzeit, Konferenz oder Party laden ihre Fotos ueber einen geteilten Link hoch, und die App ordnet sie in Echtzeit zu Mosaik-Kunst an. Stell dir ein Portrait des Brautpaars vor, zusammengesetzt aus hunderten Gaeste-Fotos, das sich live aktualisiert, wenn neue Uploads reinkommen. Das Backend macht rechenintensive Bildverarbeitung: ein Zielbild in Kacheln zerlegen, Kostenmatrizen berechnen, um hochgeladene Fotos den Kachelpositionen zuzuordnen, das Zuordnungsproblem loesen und das finale Compositing rendern.
Im Dezember 2024 habe ich mich fuer SST auf AWS entschieden. Neon fuer Serverless Postgres, Drizzle ORM, TypeScript-Backend mit Hono-Routes, AWS IoT MQTT fuer Echtzeit-Updates, SQS fuer Mosaik-Jobs, S3 fuer Medien. SST versprach Infrastructure-as-Code mit minimalem Boilerplate. Fuer einen Solo-Entwickler, der schnell shippen will, schien das richtig.
Eine Weile war es das auch. Auth, Event-Management und Mosaik-Request-Handling waren in etwa zwei Wochen fertig.
Dann kam Maerz 2025.
196 Commits. Fast keiner davon war ein Feature. Das Commit-Log: fixed docker for deployment, reverted docker, revert docker, added changes to docker, fixed docker, fixed docker, fixed docker. Allein am 10. Maerz 27 Commits, fast alle Docker- und Deploy-Fixes. Der Mosaik-Generator ist eine Python-Pipeline mit schwerer Bildverarbeitung, und die in einen Serverless-Container zu quetschen, der unvorhersehbar cold-startet, skaliert und im falschen Moment timeout-et — das war ein Kampf, den ich nicht gewinnen konnte.
Die Scaling-Commits waren schlimmer. Ueber 30 Commits, die Kapazitaet hin- und hertoggleten: set min scaling to 0, set min scaling back to 1, remove scaling, set min scaling to 0 again, revert changes to scaling. Am 28. April habe ich einen Scaling-PR gemergt, sofort revertiert, dann gefixt und erneut gemergt. Am selben Tag. Im Mai kam increased memory, changed resolution to 400 not 8k, upgraded server to 8gb ram. Ich baute nichts mehr. Ich verhandelte mit meiner Infrastruktur.
Bis Juni war die Energie weg. Ein Commit am 20. Juni. Juli hatte 4 Commits. August hatte 5. Einer davon war git ignore updated.
SST war nicht die falsche Wahl, als ich sie getroffen habe. Es ist ein gutes Tool fuer den richtigen Workload. Aber fuer eine Python-Mosaik-Pipeline mit unvorhersehbaren Speicheranforderungen war Serverless die falsche Passform. Und die Kosten dieser Entscheidung haben sich immer weiter aufgestaut.
Die Entscheidung zum Rewrite
- August 2025. Letzter Commit. “Specify the TODOs that have no owner.” Ein Housekeeping-Commit — die Art, die man macht, wenn man ein Projekt aufraeumt, an dem man eigentlich schon nicht mehr arbeitet. Dann Stille. Fuenf Monate. Null Commits vom 18. August bis zum 24. Januar 2026.
Das Projekt war nicht aufgegeben, nicht wirklich. Ich habe die ganze Zeit darueber nachgedacht. Ich wusste, was falsch war. Das Problem war, dass “was falsch war” jeden Layer betraf.
Ein Rewrite wuerde bedeuten: die SST-Infrastruktur-Dateien rausreissen (api.ts, storage.ts, queue.ts, frontend.ts, generate_mosaic_task.ts). Das gesamte TypeScript-Hono-Backend in Python umschreiben. Drizzle ORM und Neon durch SQLAlchemy und Standard-PostgreSQL ersetzen. Jeden Frontend-API-Call umverdrahten. AWS IoT MQTT durch etwas Self-Hosted ersetzen. SQS gegen eine Python-Task-Queue tauschen. Alles, ohne Features zu verlieren, die schon funktionierten.
Jeder einzelne Punkt davon ist ein grosses Projekt. Zusammen fuehlte es sich endgueltig an.
Die meisten Entwickler haben so ein Projekt. Man weiss, die Architektur ist falsch, aber die Rewrite-Kosten fuehlen sich so an, als wuerden sie einen auffressen. Zu tief drin, um neu anzufangen, zu frustriert, um weiterzumachen. Also liegt das Projekt rum. Man redet sich ein, man kommt zurueck, wenn man mehr Zeit hat. Monate vergehen.
Claude Code kam als Hebel ins Spiel, nicht als Retter. Ich hatte AI-gestuetzte Entwicklungstools verfolgt, und die Idee war simpel: Wenn ein AI-Pair-Programmer den Boilerplate uebernehmen kann, die repetitive Migrationsarbeit, das Test-Scaffolding, die Type-Generierung — dann aendert sich vielleicht die Rewrite-Rechnung. Vielleicht wird aus einem 3-Monats-Rewrite ein 3-Wochen-Sprint. Ich war nicht sicher, ob es funktionieren wuerde. Aber die Alternative war, TessellAI auf einem Feature-Branch sterben zu lassen. Also oeffnete ich am 25. Januar 2026 mein Terminal.
Was tatsaechlich passiert ist
Tag 1: 25. Januar 2026
Zwanzig Commits:
Der erste Commit war added claude.md, das Einrichten der Context-Datei fuer den AI-Assistenten. Dann ein systematischer Marsch durch eine nummerierte Aufgabenliste: Datenbankmodelle, Auth mit TDD, Media-Uploads, Mosaik-Request-Management, Celery, Mosaik-Pipeline-Integration, Frontend-Type-Generierung, erste zwei Page-Migrationen. Jeder Commit referenziert eine Aufgabennummer, weil ich die gesamte Migration in einen Plan zerlegt hatte, bevor ich eine Zeile Code geschrieben habe.
Was dieses Tempo moeglich machte: Claude Code generiert Boilerplate und Tests gleichzeitig. Scaffolding-Arbeit, die einen ganzen Tag frisst, war in Minuten erledigt. Aber jede Architekturentscheidung habe ich selbst getroffen. Python statt TypeScript, weil der Mosaik-Generator schon Python war und ich keine Lust mehr hatte, Sprachen ueber eine Container-Grenze hinweg zu bruecken. FastAPI statt Django, weil ich explizite Route-Definitionen und Pydantic-Validierung wollte, ohne ein Admin-Panel, das ich nie nutzen wuerde. Celery statt Background-Threads, weil Mosaik-Rendering minutenlang laeuft. WebSocket statt Polling, weil Nutzer erwarten, dass Fotos live erscheinen. Claude Code hat diese Entscheidungen nicht getroffen. Es hat die Umsetzung so schnell gemacht, dass ich alle an einem Tag treffen konnte.
Wochen 1-2: alles zusammenverdrahten
Die Frontend-Migration passierte Seite fuer Seite ueber die naechsten zehn Tage. Events-Management, Upload-Seiten, Mosaik-Konfiguration, die Render-Ansicht. Jede Seite wurde von SST/Hono-Endpoints auf das neue FastAPI-Backend umgestellt. Der typisierte openapi-fetch-Client fing API-Aenderungen zur Compile-Time ab; wenn ein FastAPI-Endpoint sein Response-Format aenderte, flaggte TypeScript jeden Caller, der angepasst werden musste.
WebSocket ersetzte AWS IoT MQTT. Statt IoT-Endpoints zu provisionieren und MQTT-Verbindungen ueber AWS zu managen, hatte ich eine FastAPI-WebSocket-Route, die Tile-Placement-Events broadcastete. Standard-WebSocket im Frontend. Kein AWS SDK, keine IoT-Policy-Konfiguration, keine regionsspezifischen Endpoints. Guest-Sessions liefen ueber JWT-Auth, sodass Event-Gaeste ohne Account uploaden konnten.
Dann der Squash. Commit 4e837d9, refactor: migrate from SST/serverless to FastAPI monolith backend, landete auf main: 432 veraenderte Dateien, 24.422 Einfuegungen, 11.569 Loeschungen. Die gesamte Migration in einem Diff.
Woche 3 und danach
Mit dem Monolith an Ort und Stelle liefen Features wie am Schnuerchen. Die Infrastruktur kaempfte nicht mehr gegen mich. Deployen hiess: auf einen Server pushen, nicht Cold-Starts debuggen. Der Mosaik-Generator lief im selben Python-Prozess wie die API. Speicher war vorhersehbar. Timeouts konnte ich selbst setzen.
In den ersten drei Wochen nach der Migration:
- Neue Mosaik-Stile (Sharp, Incremental) mit Multi-Feature-Cost-Estimatoren und Zwei-Phasen-Solvern
- PixiJS-WebGL-Renderer als Ersatz fuer framer-motion
- Generisches Wizard-Framework fuer mehrstufige Flows
- Per-Tile-Cropping mit Aspect-Ratio-bewusster Kompression, Luminance-Blending und Enhancement-Previews
- Galerie-ZIP-Downloads mit passwortgeschuetzten Sharing-Links
- i18n ueber 11 Locales
- High-Resolution-Render-Only-Pipeline fuer Print-Qualitaet
- Tile-Upload-Pipeline-Optimierung fuer 1.000+ Bilder
Am 16. Februar 2026 kam der Album-Pivot: Aufteilen der Media-Tabelle in EventMedia und MosaicMedia. 4-Phasen-Migration mit Abwaertskompatibilitaet bei jedem Schritt. Phase 1 erstellte neue Tabellen und migrierte Daten. Phase 2 verdrahtete Endpoints neu. Phase 3 aktualisierte Frontend-Komponenten. Phase 4 entfernte das Legacy-Modell. Jede Phase hatte ein Design-Doc, Tests und einen eigenen Commit. Alle vier gingen an einem Tag live.
In 3 Wochen nach der Migration wurden mehr Features ausgeliefert als in den vorherigen 8 Monaten auf SST. Nicht weil ich haerter gearbeitet habe. Die Commit-Frequenz im Februar war tatsaechlich niedriger als der hektische Maerz-2025-Peak. Der Unterschied war, dass jeder Commit das Produkt voranbrachte, statt nur die Lichter am Laufen zu halten.
Was gut lief
Monatliche Commits gingen von ~74 waehrend der SST-Aera auf ~105 mit Claude Code, ein Sprung von 42%. Aber der Charakter aenderte sich mehr als die Zahl. Geschaeftigster SST-Tag: 26. Maerz 2025, 41 Commits, fast alle Infrastruktur-Konfiguration. Geschaeftigster Claude-Code-Tag: 5. Februar 2026, 22 Commits inklusive Migration-Landing auf main, i18n ueber 11 Locales, SEO-Arbeit und Mosaik-Rendering-Fixes. Weniger Commits, mehr Produkt.
TDD war von Tag eins an fest eingebaut. Die Commit-Messages erzaehlen die Geschichte: “Complete authentication system with TDD,” “Complete media upload system with TDD.” Der Monolith hatte am Ende bessere Test-Coverage als die SST-Codebase je hatte, und ich musste nicht darum kaempfen. Einmal die Erwartung im Projekt-Kontext setzen und Claude Code zieht es durch.
Planung auch. 16 Design-Dokumente (~237 KB) waehrend der Claude-Code-Aera. Null waehrend SST. Brainstormen, planen, bauen. Paradoxerweise hat Planung die Dinge schneller gemacht. 20 Minuten an einem Design-Doc sparten Stunden an Nacharbeit. Der Album-Pivot ist das klarste Beispiel: 4 Phasen, jede mit Abwaertskompatibilitaet, jede baut auf der vorherigen auf.
Das groessere Learning fuer mich persoenlich: Architekturentscheidungen, die sich endgueltig angefuehlt haben, wurden umkehrbar. Dieses Projekt war 5 Monate tot und kam zurueck. Das veraendert, wie ich ueber Architektur denke.
Was nicht gut lief
Claude Code produzierte manchmal mehr Code als noetig. Die Spotlight-Animation ist das klarste Beispiel. Gebaut, ausgeliefert, innerhalb von Tagen entfernt, von Grund auf mit PixiJS neu gebaut. Wenn Code-Generierung Minuten statt Stunden kostet, ist die Versuchung gross, erst zu bauen und danach zu evaluieren. Das funktioniert, bis man die Arbeit von gestern loescht.
Die Git-Hygiene hat gelitten. Dieser 432-Dateien-Squash-Commit ist keine gute Praxis. Ich habe waehrend der Migration Geschwindigkeit ueber saubere History gestellt. Granularere Commits haetten das Debugging einfacher und die History nuetzlicher gemacht. Wenn man mit einem AI-Assistenten schnell unterwegs ist, sammeln sich Aenderungen auf Branches an, die man haette aufteilen sollen.
Das hier ist am wichtigsten: Man muss trotzdem wissen, was man tut. Claude Code fuehrt Entscheidungen aus. Es trifft sie nicht. Klare Richtung brachte gute Ergebnisse. Vage Richtung brachte mittelmaessigen Code. Falsche Richtung mit hoher Geschwindigkeit ist immer noch falsche Richtung. Jedes gute Ergebnis in dieser Migration laesst sich auf eine bewusste Entscheidung zurueckfuehren, die ich getroffen habe, bevor Claude Code irgendetwas geschrieben hat.
Noch etwas: Zum Zeitpunkt dieses Artikels lebt die Migrationsarbeit immer noch auf fix/improved-tessellai, nicht auf main. Die Migration ist passiert. Die Features sind ausgeliefert. Aber der finale Merge und das Production-Deployment stehen noch aus. Echte Projekte haben lose Enden, und ich erwaehne das lieber, als so zu tun, als waere alles abgeschlossen.
Was ich jemandem sagen wuerde, der auf Technical Debt sitzt
Die Rewrite-Kosten sind nicht mehr das, was sie mal waren. Die Arbeit, die Rewrites frueher prohibitiv gemacht hat — Boilerplate, Test-Scaffolding, API-Migration, Type-Generierung — ist genau das, was AI-Coding-Tools am besten koennen. Aus einem 3-Monats-Rewrite koennen 3 Wochen werden. Nicht umsonst, aber machbar.
Die Entscheidungen triffst immer noch du. Claude Code hat mir nicht gesagt, dass ich von Serverless auf Monolith wechseln soll. Es hat nicht FastAPI oder Celery gewaehlt. Es hat den Album-Pivot nicht designed. Das waren meine Calls, aus Jahren des Softwarebauens. Man muss wissen, was man will, bevor das Tool einem helfen kann, es zu erreichen.
Was fuer mich funktioniert hat: mit dem Backend anfangen, die API zum Laufen bringen, bevor man das Frontend anfasst. Das Frontend Seite fuer Seite migrieren. Abwaertskompatibilitaet beibehalten, damit man zurueckrollen kann. Design-Docs vor dem Code schreiben. Tests von Tag eins.
TessellAI ist ein Fotomosaik-Generator fuer Live-Events. Gaeste laden Fotos hoch, die App setzt sie in Echtzeit zu Mosaiken zusammen. Immer noch in Entwicklung. Die Migration hat es von der Intensivstation zurueck in die aktive Entwicklung gebracht.
Falls du selbst eine Migration hinter dir hast — ich wuerde gern hoeren, wie es gelaufen ist. Was schiefging, was funktioniert hat, was du anders machen wuerdest.
Migration in Zahlen
| Metrik | SST-Aera (Serverless) | Claude-Code-Aera (Monolith) |
|---|---|---|
| Zeitraum | Dez 2024 - Aug 2025 (8 Monate) | 25. Jan - 16. Feb 2026 (3 Wochen) |
| Monatliche Commit-Velocity | ~74 Commits/Monat | ~105 Commits/Monat (+42%) |
| Aktivster Tag | 41 Commits (Infra-Fixes) | 22 Commits (Features) |
| Docker/Infra-Fix-Commits | 70+ | 0 |
| Design-Docs geschrieben | 0 | 16 (~237 KB) |
| Projektstillstand | 5 Monate (null Commits) | N/A |
| Die grosse Migration | N/A | 432 Dateien, +24.422 / -11.569 Zeilen |
FAQ
Warum Serverless zu Monolith statt umgekehrt?
TessellAIs Mosaik-Generator macht schwere Bildverarbeitung mit unvorhersehbarem Speicherbedarf und minutenlangen Ausfuehrungszeiten. Serverless-Container cold-starten, skalieren unvorhersehbar und laufen in Timeouts. Ein Monolith mit Celery brachte vorhersehbaren Speicher, keine Cold-Starts, und den Generator im selben Prozess wie die API. Die richtige Architektur haengt vom Workload ab.
Wie viel hat Claude Code geschrieben vs. du?
Claude Code hat Boilerplate, Test-Scaffolding und repetitive Migrationsarbeit generiert. Die Architekturentscheidungen habe ich getroffen: FastAPI statt Django, Celery statt Background-Threads, WebSocket statt Polling, der 4-Phasen-Album-Pivot. Klare Richtung brachte gute Ergebnisse. Vage Richtung nicht.
Kann Claude Code eine Migration dieser Groessenordnung handlen?
432 Dateien, 24.422 Einfuegungen, 11.569 Loeschungen. Es hat einzelne Aufgaben gut gehandlet, wenn sie in einen nummerierten Plan mit klarem Scope zerlegt waren. Definierte Tasks (diesen Endpoint umschreiben, Tests fuer diesen Service hinzufuegen, diese Seite migrieren) liefen sauber. Unklare Anforderungen weniger.
Wie lange haette es ohne AI gedauert?
Meine Schaetzung: 2-3 Monate Vollzeit. Claude Code hat es auf etwa 3 Wochen komprimiert. Die Zeitersparnis kam vom Boilerplate, Tests und der typsicheren API-Migration, nicht von der Architektur.
Was wuerdest du anders machen?
Granularere Commits waehrend des Sprints. Der 432-Dateien-Squash hat das Debugging schwieriger gemacht. Mehr Evaluation vor dem Bauen. Die Spotlight-Animation wurde gebaut und innerhalb von Tagen verworfen. Design-Docs von Tag eins.