<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anna Hartung</title>
    <description>The latest articles on DEV Community by Anna Hartung (@mehartung).</description>
    <link>https://dev.to/mehartung</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3046201%2F24328277-ec66-4e03-bef6-48535deac671.PNG</url>
      <title>DEV Community: Anna Hartung</title>
      <link>https://dev.to/mehartung</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mehartung"/>
    <language>en</language>
    <item>
      <title>AI Writes the Code Now — Which Is Exactly Why Architecture Matters More</title>
      <dc:creator>Anna Hartung</dc:creator>
      <pubDate>Wed, 10 Jun 2026 14:03:58 +0000</pubDate>
      <link>https://dev.to/mehartung/ai-writes-the-code-now-which-is-exactly-why-architecture-matters-more-193c</link>
      <guid>https://dev.to/mehartung/ai-writes-the-code-now-which-is-exactly-why-architecture-matters-more-193c</guid>
      <description>&lt;p&gt;&lt;em&gt;By Anna Hartung — H-Studio Berlin&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There's a comfortable story going around: AI coding tools made architecture less important. If you can generate a feature in thirty seconds and regenerate it when it breaks, who cares about clean boundaries? Just vibe it.&lt;/p&gt;

&lt;p&gt;The data from 2024–2025 tells a less comfortable story. We're producing code faster than ever — and a measurable amount of it is the kind you pay for later. AI didn't make architecture optional. It made the lack of it cheaper to create and more expensive to live with.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the data actually shows
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.gitclear.com/ai_assistant_code_quality_2025_research" rel="noopener noreferrer"&gt;GitClear's 2025 report&lt;/a&gt;, analyzing over 200 million changed lines of code, found a few things worth sitting with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Copy-pasted code overtook refactored ("moved") code for the first time&lt;/strong&gt; in 2024. Cloning rose while restructuring fell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactoring collapsed&lt;/strong&gt; — lines associated with refactoring dropped from about 25% of changes in 2021 to under 10% in 2024.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duplicate code blocks spiked&lt;/strong&gt; — the frequency of copy-pasted blocks rose sharply as AI assistants went mainstream (&lt;a href="https://www.devclass.com/ai-ml/2025/02/20/ai-is-eroding-code-quality-states-new-in-depth-report/1626250" rel="noopener noreferrer"&gt;devclass summary here&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Churn went up&lt;/strong&gt; — the share of new code revised or reverted within two weeks of being committed climbed year over year, a proxy for "shipped before it was understood."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Academic work is pointing the same direction: a 2025 study on &lt;a href="https://arxiv.org/abs/2512.11922" rel="noopener noreferrer"&gt;vibe coding in practice&lt;/a&gt; documents the flow benefits &lt;em&gt;and&lt;/em&gt; the technical-debt cost, and argues for guidelines to keep it sustainable.&lt;/p&gt;

&lt;p&gt;None of this says AI coding is bad. It says AI optimizes for &lt;em&gt;producing&lt;/em&gt; code, and producing is not the same as &lt;em&gt;structuring&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI pushes you toward duplication, not design
&lt;/h2&gt;

&lt;p&gt;It's not mysterious once you look at the mechanics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI generates; it rarely refactors.&lt;/strong&gt; Asked for a feature, a model gives you a working block. Asked for a similar feature, it gives you another working block — not "extract the shared logic from the first one." Left unchecked, that's literally how you get a 4x rise in duplication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It optimizes locally.&lt;/strong&gt; A model is brilliant at the next function and blind to your system. It doesn't know that the thing it just wrote belongs behind an existing interface, or that you already have a service for this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It removes the friction that used to force structure.&lt;/strong&gt; Writing the third near-identical handler by hand used to hurt enough that you'd stop and abstract. Generation removes the pain — and with it, the signal that told you to refactor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Review degrades.&lt;/strong&gt; When code arrives faster and "looks right," reviewers rubber-stamp more. The fast path is to approve, not to ask "should this exist at all?"&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for how you build
&lt;/h2&gt;

&lt;p&gt;The counter-move isn't to ban AI — it's genuinely a productivity unlock. The move is to put the human effort where the model is weakest: &lt;strong&gt;structure.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep architecture decisions human and explicit.&lt;/strong&gt; Boundaries, the data model, public interfaces, where state lives — these are the expensive-to-change decisions, and they're exactly what AI won't make well for you. Decide them deliberately, up front.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat AI like a very fast junior.&lt;/strong&gt; Fantastic at filling in a well-defined function. Not the one you let define your module boundaries or your schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make refactoring and de-duplication explicit review criteria.&lt;/strong&gt; "Does this duplicate something we have?" and "does this belong behind an existing interface?" should be checklist items, not vibes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defend test coverage.&lt;/strong&gt; Generated code without tests is the fastest way to build something nobody dares to touch in six months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch churn as a signal.&lt;/strong&gt; If lots of fresh code is being rewritten within days, that's not velocity — it's rework wearing velocity's clothes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The architecture-first take
&lt;/h2&gt;

&lt;p&gt;Here's the reframe. In a world where typing code was the bottleneck, "just write it" was a defensible default. Now that generating code is nearly free, the bottleneck moves entirely to the decisions code &lt;em&gt;can't&lt;/em&gt; make for itself: what the system is, how its parts relate, what's allowed to depend on what. Those decisions were always the expensive ones. AI just stripped away the manual labor that used to hide how much they mattered.&lt;/p&gt;

&lt;p&gt;So the studios and teams that win the next couple of years won't be the ones that generate the most code. They'll be the ones whose generated code lands inside an architecture good enough to absorb it — instead of turning into the 12-month rewrite the churn numbers are quietly predicting.&lt;/p&gt;

&lt;p&gt;Use the AI. Keep the architecture human. That's the whole playbook.&lt;/p&gt;




&lt;p&gt;I'm Anna Hartung, founder of &lt;a href="https://www.h-studio-berlin.de/" rel="noopener noreferrer"&gt;H-Studio&lt;/a&gt;, an architecture-first engineering studio in Berlin. We spend a lot of our time making sure fast-moving code lands on a structure that can hold it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sources: &lt;a href="https://www.gitclear.com/ai_assistant_code_quality_2025_research" rel="noopener noreferrer"&gt;GitClear AI Code Quality 2025&lt;/a&gt; · &lt;a href="https://www.devclass.com/ai-ml/2025/02/20/ai-is-eroding-code-quality-states-new-in-depth-report/1626250" rel="noopener noreferrer"&gt;devclass&lt;/a&gt; · &lt;a href="https://arxiv.org/abs/2512.11922" rel="noopener noreferrer"&gt;arXiv 2512.11922&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>coding</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Keep Your Source of Truth in the Database, Not in Files: A Pattern for Document-Heavy Apps</title>
      <dc:creator>Anna Hartung</dc:creator>
      <pubDate>Wed, 10 Jun 2026 14:00:43 +0000</pubDate>
      <link>https://dev.to/mehartung/keep-your-source-of-truth-in-the-database-not-in-files-a-pattern-for-document-heavy-apps-546g</link>
      <guid>https://dev.to/mehartung/keep-your-source-of-truth-in-the-database-not-in-files-a-pattern-for-document-heavy-apps-546g</guid>
      <description>&lt;p&gt;Most apps that handle a lot of documents — client portals, legal and case systems, funding or insurance workflows, anything with uploads and approvals — quietly drift into the same anti-pattern. The files become the real state of the system. The "status" of a case is whatever the latest PDF in the folder says. Who's allowed to see what is decided by where a file lives. The database, if there is one, ends up as a thin index over a pile of documents.&lt;/p&gt;

&lt;p&gt;It feels natural, and it's a trap. Here's the pattern we reach for instead, and why it pays off.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule: the database is the system of record; files are just managed assets
&lt;/h2&gt;

&lt;p&gt;State lives in the database. Documents live in object storage. The database owns the truth — statuses, ownership, permissions, the activity history — and each file is represented by a row with metadata and access rules, not by its existence in a folder.&lt;/p&gt;

&lt;p&gt;Concretely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every domain object is a real record&lt;/strong&gt; — case, request, task, agreement, billing state — with explicit status fields and transitions, not implied by which documents exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files are assets, referenced from the database.&lt;/strong&gt; The blob sits in object storage; the row holds the metadata, the owner, the permissions and the link.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access is checked against the data model&lt;/strong&gt;, by role &lt;em&gt;and relationship&lt;/em&gt; — "can this user see &lt;em&gt;this&lt;/em&gt; record," not just "is this user logged in."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State changes are logged as events.&lt;/strong&gt; Sensitive transitions write an activity record, so "who did what, when" is a first-class part of the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why it's worth the extra work
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Auditability.&lt;/strong&gt; When the truth is in the database and transitions are logged, you can answer "what happened to this case and who touched it" precisely. A folder of files can't tell you that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access control becomes possible.&lt;/strong&gt; You can't reliably enforce "this paralegal sees only their assigned cases" when permission is a function of folder structure. When access is a check against records and relationships, you can.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrity.&lt;/strong&gt; Documents get renamed, re-uploaded, deleted. If they're your source of truth, every one of those is a potential corruption of state. As assets pointed to from authoritative records, they're replaceable without losing the truth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can actually reason about the system.&lt;/strong&gt; Statuses, transitions and ownership in a schema are something you can query, validate and test. "The newest PDF wins" is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  A minimal shape
&lt;/h2&gt;

&lt;p&gt;You don't need anything exotic. A typical version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Postgres (or similar) as the single source of truth for records, status, permissions and events&lt;/li&gt;
&lt;li&gt;Object storage (S3-style) for the file bytes&lt;/li&gt;
&lt;li&gt;A metadata row per file: owner, related record, type, access scope, timestamps&lt;/li&gt;
&lt;li&gt;Role- and relationship-based access checks on every protected route&lt;/li&gt;
&lt;li&gt;An append-only activity log for sensitive state changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The expensive-sounding parts — the event log, the per-record access checks — are cheap to add at the start and very painful to retrofit once files have already become your de-facto database.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trade-offs (so this isn't a sales pitch)
&lt;/h2&gt;

&lt;p&gt;This pattern is overkill for a simple file share or an internal tool three people use. If there are no real roles, no compliance surface and no need to audit, a folder and a spreadsheet are fine — don't build a state machine to store five PDFs.&lt;/p&gt;

&lt;p&gt;It earns its keep the moment you have multiple roles, sensitive data, approvals, or anyone who will later ask "who saw this and when": legal, healthtech, fintech, B2B client portals, anything touching personal data under GDPR. That's exactly where the file-as-truth approach fails most expensively.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one-line version
&lt;/h2&gt;

&lt;p&gt;If a document determines what your system &lt;em&gt;does&lt;/em&gt; — who can act, what state something is in, what happens next — that decision belongs in your database, with the file as a managed asset hanging off it. Treat files as the source of truth and you've built a filing cabinet. Treat the database as the source of truth and you've built a system.&lt;/p&gt;




&lt;p&gt;I'm Anna Hartung, founder of &lt;a href="https://www.h-studio-berlin.de/" rel="noopener noreferrer"&gt;H-Studio&lt;/a&gt;, an architecture-first engineering studio in Berlin. We build document- and workflow-heavy platforms where this distinction is usually the difference between a product and a mess.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Building for the Surge — What We Learned Architecting a System for 10,000+ Users at Once</title>
      <dc:creator>Anna Hartung</dc:creator>
      <pubDate>Wed, 23 Apr 2025 10:55:03 +0000</pubDate>
      <link>https://dev.to/mehartung/building-for-the-surge-what-we-learned-architecting-a-system-for-10000-users-at-once-200c</link>
      <guid>https://dev.to/mehartung/building-for-the-surge-what-we-learned-architecting-a-system-for-10000-users-at-once-200c</guid>
      <description>&lt;h1&gt;
  
  
  Building for the Surge: Architecting for 10,000+ Users at Once
&lt;/h1&gt;

&lt;p&gt;When tickets for a big event go on sale, traffic doesn’t gradually increase.&lt;br&gt;&lt;br&gt;
It spikes.&lt;br&gt;&lt;br&gt;
All at once. Thousands of people hitting &lt;strong&gt;Buy Now&lt;/strong&gt; in the same moment.&lt;/p&gt;

&lt;p&gt;That’s the scenario we had to design for when building &lt;strong&gt;EventStripe&lt;/strong&gt; — a ticketing platform with one key constraint:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The system had to stay responsive under 10,000+ concurrent users within the first minute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This wasn’t about long-term scalability or graceful degradation.&lt;br&gt;&lt;br&gt;
It was about surviving the first 60 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we focused on
&lt;/h2&gt;

&lt;p&gt;We’ve worked on plenty of high-load platforms before, and we stick to a few architectural rules when the stakes are this high:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Isolate traffic domains&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We split payments, seat reservations, and admin panels into separate services. No shared failures, independent scaling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use queues and prioritize&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Payment spikes aren’t just traffic — they’re money. We used retry logic, backoff strategies, and metrics to keep the system graceful under pressure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make monitoring a first-class citizen&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Grafana dashboards and ELK logs gave us zone-level visibility in real time. Saturation. Queue depth. Error rates. If it blinked — we saw it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don’t fear launch-day deploys&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Jenkins pipelines with rollback and canary options gave us confidence. If something had to change mid-spike, we were ready.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simulate real chaos&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Load tests weren’t theoretical. We mimicked real user flows, used real API limits, and stress-tested until the system stopped blinking.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Stack (if you’re curious)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Java 20 + Spring (backend)
&lt;/li&gt;
&lt;li&gt;Next.js (frontend)
&lt;/li&gt;
&lt;li&gt;Docker + Kubernetes
&lt;/li&gt;
&lt;li&gt;Jenkins, Grafana, ELK&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;We ran tests simulating &lt;strong&gt;9,000+ active users&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The system held.&lt;br&gt;&lt;br&gt;
No slowdowns. No unhandled spikes. Just tickets sold.&lt;/p&gt;

&lt;p&gt;It’s not a magic formula — just careful architecture and a lot of rehearsal.&lt;/p&gt;




&lt;p&gt;Have you built for traffic surges before?&lt;br&gt;&lt;br&gt;
What helped your system survive?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This project was designed and tested by our team at &lt;a href="https://www.h-studio-berlin.de/" rel="noopener noreferrer"&gt;H‑Studio&lt;/a&gt;, where we focus on building resilient, high-load systems for SaaS and platforms.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>devops</category>
      <category>architecture</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
