ENGINEERING6 MIN READ28 AUG 2026
The Evolution of a Platform
Four and a Half Years of Technological Growth of a System and a Backend Engineer who grew with it
Marija Nešić
Backend Developer

Long-term project retrospectives are rarely just about the evolution of software. Just as often, they reveal how an engineer’s approach to architecture, trade-offs, and technical decision-making evolves through the same process.
When you spend enough time watching a system grow, it becomes clear that it is not only the code that develops. Your ability to recognize recurring patterns, distinguish symptoms from root causes, and determine when optimization is enough, and when the architecture itself needs to change, develops as well.
In my case, four and a half years of developing a content platform represented exactly that kind of process. During that time, the platform evolved from a simple WordPress blog into a system that now powers an entire network of portals. At the same time, its development became a kind of professional laboratory where I learned how systems mature, how technical debt accumulates, and how architectural decisions, good or bad, shape the maintainability of a project years down the line.
The Initial Stage: Simple Architecture and Its Natural Limits
The project started as a standard WordPress blog with a clear and relatively modest technical scope. As the volume of content and the number of functional requirements grew, the codebase gradually expanded into four different themes. New business requirements were regularly addressed by overriding existing functionality in combination with ACF, which, in practice, took on the role of an informal content modeling system.
This architecture worked within the boundaries it had originally been designed for, but it began showing clear signs of strain in three areas.
Growing traffic directly degraded system performance. Simultaneous editing of the same article by two editors was not technically supported by the WordPress architecture. And real-time content delivery, live event coverage via WebSocket connections, for example during sports events or other breaking news, placed additional strain on the system precisely during periods of peak traffic, when the combination of a large number of concurrent readers and a constant stream of new data presented the greatest operational challenge.
The Architectural Decision: Moving to Wagtail
The move to Wagtail was driven by clearly identified limitations of the existing architecture, rather than a generic desire to adopt new technology. The key technical criteria were:
• Template layer flexibility, Wagtail made it possible to dynamically define and select templates in a way that the WordPress theme architecture did not structurally support.
• Editorial workflow efficiency, the goal was to allow editors to edit both individual articles and the article feed on each page with as few steps as possible and without relying on workarounds.
• Concurrent content editing, the ability for two users to work on the same article simultaneously. This functionality was unavailable in the previous system but was an important prerequisite for an efficient newsroom workflow when multiple editors needed to work on the same content at the same time.
Architectural Separation: From Plugin Logic to Core and Modular Add-ons
One of the most technically demanding parts of the migration involved structurally separating functionality that had been implemented in WordPress as a plugin integrated into the theme and transforming it into components with a clear, independent architecture in Wagtail.
The process took place in two stages. The functionality was initially integrated as part of the core system and was later extracted into a separate, modular Wagtail application that could be enabled selectively for individual portals or themes as needed.
The technical challenge was not the extraction itself, but rather analyzing and separating dependencies that had never been designed with modularity in mind. Functionality that had grown organically within the core contained implicit assumptions about components that would always be present. Those boundaries had to be explicitly defined before extracting the functionality into an independent add-on was even possible.
This process reinforced a broader architectural principle: component optionality should be defined as a requirement during the design phase, rather than introduced later when modularity becomes necessary.
Postponing this decision directly increases the cost of separating the component later, in proportion to the amount of time the functionality has remained tightly coupled to the core.
Addressing Performance Limitations: Static Delivery and Query Optimization
Alongside the architectural separation, we were dealing with a concrete operational problem: high system load during peak traffic periods was causing infrastructure instances pods to fail.
The solution was implemented through static content generation. Instead of allowing every user request to directly place load on the application and database, content was generated in advance and served as static files. This reduced the load to a level the infrastructure could reliably handle.
Another parallel workstream involved systematically analyzing the application code and eliminating N+1 queries, cases in which a single request for a list of content would implicitly generate an additional database query for every related object.
This class of problem typically remains invisible in a development environment with a limited amount of test data. It only becomes apparent at production-scale data volumes and traffic levels, where it can directly determine whether a system remains stable under load.
Optimizing these queries, by explicitly defining them instead of relying on the ORM’s default behavior, did not introduce any visible new functionality, but it was directly responsible for maintaining system stability during periods of peak load.
What I Learned as a Backend Engineer
Looking at four and a half years of continuous development on this project, the experience helped me build several lasting professional competencies:
• Recognizing the architectural limits of a system, the ability to identify when an existing architecture is approaching the limits of what it can support before those limitations become operational problems.
• Distinguishing performance problems that require code optimization from those that require architectural change, a clear example is the difference between N+1 queries, which can be addressed through code-level optimization, and load-related problems that required an architectural change through static content generation.
• Designing for modularity and system optionality from the beginning, understanding that separating the core from add-ons creates significantly more technical debt when that separation has not been planned in advance.
• Managing technical debt in long-running projects, gaining practical experience in recognizing when a temporary solution needs to be formalized into a permanent architectural decision rather than being allowed to accumulate as an implicit assumption within the system.
Looking back today, I realize that the greatest value of this project for me is not the fact that I spent four and a half years working with WordPress or Wagtail. What matters far more is that I had the opportunity to observe a system as it moved through different stages of its lifecycle, from a simple implementation, through rapid growth, to the point where architecture became a key factor in its long-term sustainability.
That kind of experience changes the way you think.
Technologies, frameworks, and tools will inevitably change, but the principles behind well-designed systems remain. I learned that a performance problem is not always a code problem, that modularity delivers the most value when it is planned from the beginning, and that technical debt is easiest to address while it is still small enough to manage.
That is why I do not associate the skills I gained from this project with any particular framework or platform. Instead, they represent a way of thinking that I can apply to any backend system: the ability to understand why an architecture works, recognize when it stops working, and ensure that its evolution supports product growth rather than slowing it down.
Today, I consider that the most valuable outcome of working on this project.
About the author
Keep talking
Talk to the engineering team
If you're shipping something into production and want a sanity check from people who've done it, we'd be glad to compare notes.