Felipe Hlibco is a Silicon Valley engineering leader and former Senior Partner Engineer at Google leading the transition of enterprises messaging workloads from SMS to RCS. With 20+ years of experience, ranging from co-founder and CTO roles to co-authoring the Rich Communication Language (RCL) industry specification — Felipe is a leading voice at Conversational AI.

A frequent speaker and judge at forums like AWS, Cloudflare, and GitHub, he provides unique insights into building secure and resilient AI messaging products and scaling global developer ecosystems. Felipe’s mission is to bridge the gap between technical complexity and business impact, ensuring that as we “AI-fy” the world, we remain grounded in human-first innovation and safety.

Watch the video

Posts

6 Jan 2022

Data Plus Architecture: Integrating Data into Design

I’ve watched three organizations try to migrate their data at scale this past year. All three started the same way — someone said “we need better analytics.” All three hit the same wall: the architecture wasn’t built for data flow, so extracting anything meant duct-taping brittle pipelines onto systems that fought back every time you queried them.

This is how it always goes. Data gets treated like exhaust — a byproduct of the “real” work of building apps. You ship features, hit deadlines, and then someone from analytics shows up asking for a warehouse. That’s when you realize your microservices scattered data across a dozen schemas, and cross-service queries are now a nightmare you can’t wake up from.

30 Dec 2021

PadCare Labs: AI for Social Impact Case Study

I spend most of my time thinking about developer tools, APIs, and cloud infrastructure. Interesting problems, sure. Life-changing? Not exactly. Every once in a while, though, I come across a use of technology that reminds me why I got into this field in the first place.

PadCare Labs is an Indian startup that processes menstrual hygiene waste. Not a glamorous pitch. Not the kind of thing that gets covered at major tech conferences. But the engineering behind it is solid — and the social impact is real in ways that most “AI for good” marketing copy only pretends to be.

9 Dec 2021

The Log4Shell Aftermath: Why Maintenance is Creation

A critical vulnerability in Apache Log4j dropped this morning. CVE-2021-44228. Remote code execution in a logging library embedded in basically everything Java touches. Scrambling starts now, if it hasn’t already.

Writing this the same day the news broke because the conversation already heads the wrong way. Patching, scanning, who updated dependencies fastest — those things matter. Symptoms, though. All symptoms.

The disease? The industry treats maintenance like it counts for nothing.

27 Nov 2021

TypeScript 4.5: The Awaited Type and Promise unwrapping

TypeScript 4.5 dropped on November 17th, and honestly? The feature I’m most excited about is Awaited<T>. Not exactly headline material — it’s a utility type, and utility types don’t exactly trend on Hacker News. But this one fixes a class of problems I’ve been wrestling with for years, and the solution is surprisingly elegant.

The problem Awaited actually solves #

Ever written a generic function that takes a Promise<T> and tried to extract what it actually resolves to? Yeah. Before 4.5, TypeScript had no built-in way to recursively unwrap nested promises — and believe me, I tried.

9 Nov 2021

Dapr Acceptance into CNCF: Logic Decoupling

Last week the CNCF TOC voted to accept Dapr as an incubating project. I’ve been watching Dapr since its Microsoft launch in 2019 — mostly with skepticism, if I’m honest — and this feels like the right moment to talk about what makes it different from the dozen other “cloud-native” projects begging for attention.

The short version? Dapr doesn’t try to be a platform. It’s a set of building blocks that sit between your application and whatever infrastructure you happen to be running on. That distinction matters more than it sounds.

25 Oct 2021

Expanding RCS Reach: Carrier Connectivity Milestones

The RCS landscape in late 2021 looks nothing like it did a year ago. Not because of some flashy feature drop, but because the connectivity fabric — the actual plumbing that lets RCS messages flow between carriers — has hit a density that changes the math for operators still sitting on the fence.

I’ve been watching this space pretty closely, and honestly? The infrastructure story is more compelling than whatever new emoji reactions just shipped.

14 Oct 2021

Node.js 17: OpenSSL 3.0 and Improved Stack Traces

Node.js 17 drops next week, and the headline change is one that’ll cause some headaches: OpenSSL 3.0 replaces OpenSSL 1.1.1.

This isn’t a minor version bump. OpenSSL 3.0 tightens restrictions on which algorithms and key sizes are allowed by default. If your application (or more likely, one of your dependencies) uses algorithms that OpenSSL 3.0 considers legacy, you’ll start seeing ERR_OSSL_EVP_UNSUPPORTED errors. No deprecation warning period — just errors.

As a Current (non-LTS) release, Node 17 won’t run in most production environments. That’s actually the point. It gives the ecosystem time to find and fix compatibility issues before OpenSSL 3.0 ships in Node.js 18 LTS, which is the release that’ll matter for production workloads.

12 Oct 2021

Psychological Safety in Knowledge Sharing

A few months into my time at Google, I watched a junior engineer ask a question in a team meeting that I thought was obvious. The answer was in the documentation—technically. It was covered in the onboarding guide—sort of. Three senior engineers had the answer off the top of their heads.

What struck me wasn’t the question. It was the silence before someone answered.

Two full seconds of silence where I could feel the junior engineer regretting asking.

30 Sep 2021

Retaining Talent through Developer Experience (DevEx)

I lost good engineers to bad tooling—not once, but at every company where the build pipeline rotted and leadership shrugged.

Not officially, of course. The exit interview says “career growth” or “new opportunity”—the usual script. But in the months before departure, the complaints ran identical: slow CI, flaky tests, outdated docs, a deployment process requiring three manual steps and a Slack message to someone in another timezone. Death by a thousand paper cuts.

28 Sep 2021

The Shape of the Edge in Modern Data Centers

There’s a Gartner prediction floating around that 75% of enterprise data will be created and processed outside traditional data centers by 2025. Up from roughly 10% a few years ago.

I don’t know if 75% is exactly right. Gartner predictions have a habit of being directionally correct but numerically ambitious — like that friend who’s always “about to start a startup.” What I do believe is that the center of gravity for compute is shifting, and the architecture of that shift matters more than whatever marketing label gets slapped on it.

3 Sep 2021

TypeScript 4.4: Aliased Conditions and Flow Analysis

TypeScript 4.4 shipped last week, and the feature I keep reaching for isn’t the one I expected.

I figured the new strictness flags would dominate my attention. They didn’t. Instead, it’s the control flow analysis of aliased conditions that’s quietly changing how I write type guards. The feature is simple enough to explain in a paragraph, but the downstream effects on code organization are larger than the changelog suggests.

The Problem Before 4.4 #

Here’s a pattern every TypeScript developer has written:

19 Aug 2021

Sustainable Software: Measuring our Carbon Footprint

I spent most of my career thinking about software performance in terms of latency, throughput, and cost. CPU cycles per request. P99 response times. Monthly AWS bills. Those are the metrics that show up in dashboards; those are the numbers managers care about.

Carbon emissions never made the list.

That’s starting to change, and I think it’s worth paying attention — not because sustainability is trendy (though it is) but because the numbers are genuinely staggering once you look at them.

26 Jul 2021

Rethinking Errors, Warnings, and Lints in Large Codebases

Last week I opened a pull request on one of our older services at TaskRabbit and got hit with 347 ESLint warnings. Not errors. Warnings. The build passed, the tests passed, and the PR got merged. Nobody looked at a single one of those 347 signals.

That moment bothered me more than it should have.

I’ve been managing large codebases for a while now, and the way most teams handle the spectrum between errors, warnings, and lints is — to put it politely — chaotic. We tend to treat them as a binary: either something blocks the build or it doesn’t. The nuance in between? Lost. Completely.

17 Jun 2021

Sir Tim Berners-Lee and the Ethics of Web Ownership

There’s an irony in Tim Berners-Lee’s position that I can’t stop thinking about. He invented the World Wide Web as an open, decentralized system for sharing information. Thirty-two years later, he’s building tools to reclaim it from the companies that centralized it.

The web was supposed to be ours. Berners-Lee designed it that way — open protocols, no gatekeepers, anyone can publish, anyone can read. In the early years, that’s roughly how it worked. Personal websites, independent forums, distributed communities linked together by hypertext.

28 May 2021

Data Mesh: Decentralized Ownership in Practice

About a year ago I wrote about why data lakes are failing. The gist: organizations dump everything into a centralized store, a small data team becomes the bottleneck for every analytical question, and the result is stale dashboards and frustrated stakeholders.

Zhamak Dehghani published a piece on Martin Fowler’s site in 2019 that crystallized what I’d been feeling. She called it “data mesh,” and the core argument is deceptively simple: treat analytical data the way we treat operational services. Decentralize ownership. Push responsibility to the teams closest to the data.

25 May 2021

TypeScript 4.3: Mastering the override Keyword

TypeScript 4.3 RC dropped on May 11th, and I’ve been running it on a side project for the past two weeks. The headline feature — the override keyword — fills a gap that’s bitten me more than once in large codebases.

Here’s the scenario. You’ve got a base class. You override a method in a subclass. Six months later, someone renames the base method during a refactor. Your subclass method silently becomes a new method instead of an override. No error. No warning. Just a subtle bug that passes type checking and breaks at runtime.

19 May 2021

Stack Overflow acquisition and the Future of Community

I look at Stack Overflow every day—usually before my second coffee, often multiple times after that. Most developers do. The workflow never changes: paste the error message, click the first result, scan for the accepted answer, move on.

That workflow amounts to consumption, not community.

Stack Overflow’s 2021 Developer Survey surfaced a number that stuck with me: only 44% of developers consider themselves members of the Stack Overflow community. The site pulls over 100 million monthly visitors, which makes the gap even stranger. So roughly 56 million people treat it like a reference manual. No questions asked, no answers written, no votes cast, no edits made.

27 Apr 2021

Designing for Portability with Cloud-Native Abstractions

I’ve had the “should we go multi-cloud” conversation at every company I’ve worked at. The answer is always complicated. Pure multi-cloud is expensive and operationally brutal. Full single-cloud commitment is efficient right up until pricing changes, a region goes down, or an acquisition brings a different cloud into the picture.

The pragmatic middle ground — and the one I keep coming back to — is designing for portability without necessarily deploying to multiple clouds.

6 Apr 2021

Node.js 16: Timers Promises and Apple Silicon support

Node.js 16 drops April 20th. I’ve been poking around the dev branch and the pre-release notes, and there’s enough here to warrant a proper look. Not a paradigm shift — more like a collection of practical fixes for real friction points.

Here’s what stands out.

Timers Promises Goes Stable #

This is the one I’m most excited about. The Timers Promises API has been experimental since Node.js 15, and it graduates to stable in v16.

24 Mar 2021

Temporal Node.js SDK: Orchestration for Distributed Logic

Every backend team I’ve managed eventually hits the same wall. You’ve got a multi-step operation — charge the customer, reserve inventory, send a notification, update the dashboard — and somewhere in the middle, something fails. Network blip. Downstream timeout. OOM kill. Now what?

The usual answer? A patchwork of retry logic, dead letter queues, state machines, and prayer. It works until it doesn’t. And debugging it when it doesn’t is its own special hell.

16 Mar 2021

US Carrier Pivot: The End of CCMI and Google's RCS

Back in October 2019, AT&T, Sprint, T-Mobile, and Verizon made a big joint announcement. They were forming the Cross Carrier Messaging Initiative — CCMI — to bring RCS messaging to every Android user in the US. A unified front. The carriers would handle it together.

It sounded great on paper. Four carriers, one initiative, interoperable RCS for everyone. The pitch was straightforward: replace SMS with something modern, and do it as a consortium so no single carrier has to go it alone.

25 Feb 2021

TypeScript 4.2: Preservation of Type Aliases

TypeScript 4.2 shipped on February 23rd and honestly? The feature that excites me most changes nothing about what your code does. It just changes what the compiler tells you.

Type alias preservation means the compiler finally stops expanding your carefully-named types into gibberish. You know the drill — you write something clean like type BasicPrimitive = string | number | boolean, and then every error message, every tooltip, every .d.ts file insists on showing string | number | boolean instead. As if your alias never existed.

5 Feb 2021

AWS Lambda support for Node.js 14 release

AWS announced Node.js 14 support for Lambda on February 3rd. Two days ago. I’ve already started evaluating the migration path for our serverless workloads at TaskRabbit.

Node.js 14 has been the active LTS release since October 2020, so this wasn’t a surprise. But Lambda runtime support typically lags LTS availability by several months—Node 12 followed the same pattern—and the gap means teams running Lambda in production have been stuck on Node 12 while the ecosystem moves forward. That gap closes now.

22 Jan 2021

Socio-Technical Systems: Designing for Human Cohesion

In 1968, Melvin Conway submitted a paper with a claim that’s been haunting software engineering ever since: “Any organization that designs a system will produce a design whose structure is a copy of the organization’s communication structure.”

Harvard Business Review rejected it. Not enough evidence, they said.

Fifty-two years later, every engineering leader I know treats it as a law of nature. Funny how that works.

We usually quote Conway as a warning. Your architecture will mirror your org chart whether you plan for it or not. But I’ve been thinking about it differently lately — if org structure determines system structure, then org design is architecture design. You can use that relationship intentionally.

1 Jan 2021

nasscom TechForGood: The Strategic Value of Social Good

Most companies treat social impact the way they treat office plants. Someone remembers to water them occasionally, they look nice in photos, and nobody measures whether they’re actually doing anything.

nasscom’s TechForGood initiative makes a different argument. Technology for social good isn’t a line item in your CSR budget. It’s a strategic lever that compounds over time.

I find this framing compelling because I’ve seen it work firsthand. Before moving to the Bay Area, I co-founded Doare.org in Brazil — a donation platform for non-profits that became the largest of its kind in Latin America. We built it because the problem was real and the technology to solve it was accessible. But what surprised me was how the mission attracted talent. Engineers who could have taken higher-paying jobs elsewhere chose to work on something that mattered to them. That retention advantage was worth more than any signing bonus.

23 Dec 2020

Adaptability: The Core Engineering Skill for 2021

Nine months ago my entire team went remote overnight. Not the planned, phased, “let’s pilot this for a quarter” kind of remote. The kind where you close the office on a Friday and hope Zoom works on Monday.

Some engineers barely missed a beat. Others struggled for weeks. The difference wasn’t seniority or technical skill. It was how quickly they could rewire their working habits.

I keep coming back to that observation as 2020 wraps up.

8 Dec 2020

Using Architecture Decision Records (ADRs) to Prevent Chaos

Last month I watched two senior engineers spend an entire sprint debating whether to use GraphQL or REST for a new internal API. They eventually chose GraphQL. The thing is, we’d already made that decision eight months ago for a different service — with reasoning that lived nowhere except maybe in Dave’s head. (Dave left in March.)

This happens constantly. A decision gets made in a meeting, or a Slack thread, or occasionally in someone’s head while they’re showering. Then people leave, context evaporates, and the next team walks into the same intersection and argues from scratch. Same debate, same circular reasoning, same outcome — or worse, a different one.

30 Nov 2020

Template Literal Types: Mapping APIs with Precision

TypeScript 4.1 dropped on November 17th and I’ve spent the last two weeks playing with template literal types. They’re one of those features that sounds academic until you see what they unlock for real API modeling.

The short version: you can now use backtick syntax in type positions to construct and manipulate string literal types at compile time.

type EventName = `on${Capitalize<string>}`;
// Matches "onClick", "onHover", "onSubmit", etc.

That’s not a runtime string template—it’s a type-level computation. The compiler evaluates it during type checking and narrows accordingly.

15 Oct 2020

Rosetta 2 and the Architecture of Apple Silicon

Back in 2006, Apple shipped Rosetta — a binary translation layer that let PowerPC apps run on Intel Macs. It was slow. It was imperfect. And it bought them just enough time to pull off one of the most successful architecture transitions in computing history.

Fourteen years later, they’re doing it again.

At WWDC in June, Apple announced the transition from Intel to their own ARM-based silicon. The M1 chip. And alongside it, Rosetta 2.

13 Oct 2020

Deno vs. Node: A Runtime Choice for 2021

Ryan Dahl released Deno 1.0 in May. If you don’t know the backstory—Dahl created Node.js, spent years watching it evolve in directions he regretted, then built Deno as a corrective. The “10 Things I Regret About Node.js” talk from JSConf EU 2018 is worth watching if you haven’t seen it. He lays out every design decision he wanted to undo, and honestly? It’s compelling stuff.

Five months post-launch, I’ve been kicking Deno’s tires as part of our 2021 technical planning at TaskRabbit. We’re a Node shop through and through—TypeScript, Express, GraphQL, the whole deal. So this isn’t some academic exercise for me. If Deno’s ready, it could actually simplify parts of our stack. If it’s not, I need to know exactly why—and more importantly, when it might be.

5 Oct 2020

TypeScript 4.1: Why Recursive Conditional Types Matter

The TypeScript 4.1 beta landed on September 18, and the marquee feature—recursive conditional types—is one of those additions that separates “TypeScript as better JavaScript” from “TypeScript as a serious type-level programming language.”

I’ve spent the last two weeks experimenting with the beta, and I want to walk through what recursive conditional types actually enable, why they matter for real codebases, and how the other 4.1 features complement them.

The Problem Before Recursion #

TypeScript’s conditional types (introduced in 2.8) let you express type-level if/else:

15 Sep 2020

Scaling Disaster Relief Response in Urban Environments

When I co-founded Doare.org in 2011, the problem felt straightforward: make it easy for people to donate to nonprofits in Brazil. We built a payment platform, partnered with hundreds of organizations, and somehow grew it into the largest donation platform for nonprofits in Latin America. (Still not entirely sure how that happened.)

What I didn’t expect—and what kept me up at night—was how much of the donation pipeline depended on knowing where the need actually was. A nonprofit could sign up on our platform, but if their outreach didn’t match where the crisis was unfolding, the money just sat there while people went hungry three neighborhoods over. Not exactly the outcome we were going for.

14 Sep 2020

Node.js 15: Introduction to AbortController

If you’ve done any work with fetch in the browser, you’ve probably used AbortController. It’s the standard Web API for cancelling asynchronous operations—pass an AbortSignal to a fetch call, call abort() when you want to cancel, and the browser throws an AbortError. Clean, composable, and it works.

Node.js hasn’t had this. And honestly? The absence of a built-in cancellation primitive has been one of those quiet pain points that every backend developer just… works around. Some use timeouts. Some use custom event emitters. Some reach for p-cancelable or similar libraries. None of it is standardized—every team invents their own slightly different pattern.

27 Aug 2020

Why the "New Normal" Demands Branded Messaging

Six months in, and “digital-first” isn’t a trend anymore. It’s just how things work now.

The businesses that built their customer relationships around in-person interactions—retail, banking, healthcare, hospitality—are scrambling to rebuild that trust through screens. Most of them, even the ones with decent digital teams, are getting it wrong.

The core problem isn’t technology. It’s identity.

When a brand texts you today, you get a gray bubble from a 10-digit number or some short code. No logo. No verification. No way to know if that “BANK ALERT” is actually from your bank or from someone who just bought a spoofed short code on the cheap. The FTC started tracking a surge in COVID-related scam texts back in March, and it hasn’t slowed down. In a world where phishing texts impersonate health agencies and delivery services, anonymous SMS isn’t just a branding limitation—it’s a liability signal.

1 Aug 2020

TypeScript 4.0: Variadic Tuple Types and Modern Pattern

TypeScript 4.0 beta dropped about five weeks ago, and I’ve been running it against a couple of our internal libraries at work. The headline feature—variadic tuple types—sounds academic until you try to type a function like concat or curry and realize the type system couldn’t express it before.

The stable release should land later this month. Here’s what’s worth paying attention to.

Variadic Tuple Types #

Before 4.0, tuple types were fixed-length. You could write [string, number], but you couldn’t write a generic type that spread one tuple into another. If you wanted to type a function that concatenated two arrays while preserving element types, you were stuck writing overloads. Lots of overloads.

31 Jul 2020

Moving Infrastructure Inference to Hardware Accelerators

Last quarter we moved a couple of our ML inference workloads off general-purpose CPUs and onto NVIDIA T4 GPUs. The performance gains were immediate and dramatic. The operational complexity that came with them was… also immediate.

At TaskRabbit, we use ML models for ranking and recommendation—matching Taskers to jobs, surfacing relevant categories, scoring urgency. These aren’t massive models by research standards, but they run on every request. Latency matters. Cost matters. And for a while, our CPU-based inference was both too slow and too expensive.

14 Jul 2020

Node.js 6.14.7: Security Patches and Dependency Audits

Last month, the Node.js project shipped security releases for versions 10, 12, and 14. If you’re running Node 6 in production—and I know some of you are—you got nothing.

Node.js 6 reached End-of-Life in April 2019. That was over a year ago. No more patches, no more backports, no more security fixes. The June 2020 releases addressed TLS session reuse vulnerabilities, HTTP request smuggling vectors, and DNS rebinding issues across the active release lines. Node 6? Exposed to all of them, with zero official remediation path.

22 Jun 2020

Stable Workers Threads in Node.js for High-CPU tasks

Node.js is single-threaded. Everyone knows this.

It’s also the source of the most common misconception about Node: that it can’t do CPU-intensive work. It can. Worker Threads have been stable since Node.js 12 LTS (April 2019), and they give you actual parallelism — not the cooperative multitasking of the event loop, but real OS-level threads running JavaScript in parallel.

So why, a year later, do most teams I talk to still haven’t touched them?

9 Jun 2020

Interoperability Milestones in the RCS Ecosystem

RCS has a credibility problem. For years, the pitch was “SMS but better” — rich media, read receipts, typing indicators, group chat. The features were real, but deployment was a mess. Carriers built RCS in silos, which meant your “upgraded” messages only worked if both people happened to be on the same carrier.

That’s finally changing. The first half of 2020 has produced genuine interoperability milestones, and honestly? They’re worth paying attention to.

19 May 2020

Why Data Lakes are Failing the Modern Enterprise

Gartner estimated that 85% of big data projects fail. Back in 2016, that number was 60%. It moved in the wrong direction. Data lakes sit at the center of it.

I’ve seen this firsthand. At TaskRabbit, we made data infrastructure decisions that started with optimistic architecture diagrams and ended with engineers complaining nobody could find anything. The pattern repeats across the industry; the root causes run more organizational than technical—almost always.

7 May 2020

TypeScript 3.9: Performance and the move to ESNext

TypeScript 3.9 RC dropped on April 28, and I’ve been running it against our codebase at TaskRabbit for the past week. The headline feature is performance — and the numbers are real.

Compile-Time Improvements #

The TypeScript team has been systematically attacking compilation performance for the last few releases. In 3.9, they targeted the pathological cases: large unions, deeply nested intersections, conditional types, and mapped types. Each individual PR contributes something like 5-10% improvement in specific scenarios; the compound effect is what moves the needle.

5 May 2020

Building Tech for Good during Global Lockdowns

I co-founded Doare.org in 2011. It became Brazil’s largest donation platform for nonprofits — over 4,500 organizations registered, payment infrastructure built from scratch, angel funding, the whole startup lifecycle. I left in 2014, but I still think about the problems we were trying to solve.

Watching what’s happening now has brought all of that back, in a way I didn’t expect.

The Nonprofit Digital Gap #

COVID-19 didn’t create the digital gap in the nonprofit sector. It exposed it. Most nonprofits I worked with in Brazil operated on spreadsheets and personal relationships. Donor communication happened through email blasts (if you were lucky) or phone calls. Volunteer coordination meant someone with a clipboard and a lot of patience.

28 Mar 2020

Node.js 14: Diagnostic Reports and Internationalization

Node.js 14 lands April 21. I’ve been poking at the dev branch for a few weeks now, and two things keep standing out: Diagnostic Reports graduating to stable, and full ICU internationalization data shipping by default.

Neither is glamorous. Both are the kind of thing that makes Node.js meaningfully better in production — which is exactly what I care about.

Diagnostic Reports Go Stable #

Diagnostic Reports have been experimental since Node.js 11. The concept is straightforward: when something goes wrong (a crash, a hang, a weird performance cliff you can’t explain), you generate a JSON report that captures the full state of the process. Stack traces, heap statistics, resource usage, libuv handle information, environment variables, loaded native modules. Everything you’d want in a post-mortem.

27 Mar 2020

Digital Transformation FOMO: Survival in a Remote World

Two weeks ago, my team was in the office. Now we’re fully remote, and so is everyone else.

The speed of this shift is hard to overstate. Companies that had “2021 digital transformation roadmaps” are compressing those plans into days. I’ve watched three different vendor threads blow up in my network this week alone — each one pitching some variation of “we’ll get you remote-ready in 48 hours.”

That’s not transformation. That’s panic.

3 Mar 2020

The Case for Modular Monoliths in Distributed Teams

Every architecture conversation I’ve had in the last two years eventually arrives at the same question: “When do we move to microservices?”

Not if. When.

I think that’s the wrong framing. At TaskRabbit, I manage a team of nine engineers spread across four time zones. We’ve been through the architecture discussion more than once, and what I keep coming back to is this: the coordination overhead of microservices might actually be worse than the monolith problems they’re supposed to solve.