What Counts as a Microservice?
The term "microservices" has generated plenty of debate since James Lewis and Martin Fowler's influential piece on the topic. The core definition they put forward describes services that are independently deployable out-of-process components, organized around business capabilities, communicating via lightweight HTTP interfaces rather than a heavyweight ESB. Services are language-agnostic and, crucially, do not share databases.
Some in the community argue this is little more than SOA with a modern veneer of HTTP and JSON — a concept that dates back to around 2005. Many companies already run architectures that satisfy all these criteria without ever using the word "microservice."
Fred George's talk in Barcelona pushes the definition further, arguing for much smaller units:
- Services should be 200–500 lines of code.
- Self-monitoring replaces unit tests; business monitoring replaces acceptance tests.
- The overall system is long-lived, but individual services are short-lived and disposed of as refinements drive architectural changes.
The Case for Tiny Services
The idea of a "micro microservice" — one in the 200–500 LOC range — deserves closer examination. Not every component fits comfortably in that size, but the ones that do tend to be noticeably more stable than their larger counterparts. For developers who also operate what they build, the appeal of a genuinely autonomous system is strong.
Small services offer several practical advantages:
- Their smaller surface area means development can iterate rapidly until bugs are eliminated.
- With a narrow area of responsibility, they rarely undergo the constant churn typical of larger codebases. Less change means less exposure to new bugs and regressions.
- Their resource footprint is often smaller, potentially avoiding issues like GC pauses, out-of-memory errors, and swapping.
- They may rely on only a highly reliable data store like S3, or be entirely stateless, removing single points of failure such as a relational database.
At Heroku, several production services fit the sub-500-LOC mold:
- Addons SSO: 171 LOC. Authenticates a user via OAuth, asks the API to sign a request on their behalf, then redirects. Powers
heroku addons:open. - Anvil: 337 LOC. A platform-powered build system that compiles slugs and releases them directly, bypassing
git push heroku master. - Cloner: 305 LOC. Authenticates via OAuth and makes an API call. Powers java.heroku.com.
- Zendesk SSO: 348 LOC. Creates Zendesk accounts for new Heroku users so they can open support tickets.
A handful of others come close but exceed the threshold:
- Deployhooks: 1240 LOC. Powers the Heroku Deployhooks add-on.
- Scheduler: 630 LOC. The web frontend for the Heroku Scheduler add-on.
- Vixie: 805 LOC. The backend of Heroku's Scheduler add-on, receiving instructions from the scheduler service.
A common trait across these services is their autonomy. Basic alarms exist in case they fail, but they rarely trigger. Deployment on the Heroku platform helps, but so does the fact that their concerns are narrow and stable enough that there's little room for bugs to hide.
That said, 500 LOC isn't enough to contain every component, even narrowly scoped ones — many more important services at Heroku easily exceed that limit. And replacing unit or acceptance tests with self-monitoring and business monitoring remains a step too far for many production systems.
Weighing the Costs of SOA
Service-oriented architecture offers substantial organizational and operational benefits, chiefly by enforcing hard isolation between components. But that isolation has a price: component boundaries become significantly harder to evolve over time.
The downsides of a SOA-like system are real:
- Any contract change between two services demands coordinated development and deployment on both sides — especially slow when different teams own each service.
- Data becomes widely distributed and harder to inspect and query. A data warehouse can help, but that's another component to build and run.
- The platform required to deploy new services carries overhead. Docker and Heroku reduce the burden, but new services still need dashboards, alarms, deployment tooling, and operational processes.
- Integration testing shifts from individual components to the full working system, which is inevitably slower and less transparent.
The short version: adopting a microservice architecture isn't just about building the system itself. It's also about building the tools, processes, and infrastructure to operate it. Larger companies will likely need something approaching SOA to keep making progress, but smaller shops may not benefit from rushing into it — no matter how compelling the technology looks.
Significant vendor hype surrounds SOA, which can create exaggerated expectations.



