Weekend Reading #99
Weekend Reading: A weekly roundup of interesting Software Architecture and Programming articles from tech companies. Find fresh ideas and insights every weekend.
This week: two bool.dev guides on hidden EF Core costs and consolidating microservices without losing module boundaries; Booking.com’s production investigation into Node.js resource efficiency; and LinkedIn’s move to a dedicated shuffle service for Spark and Flink.
18 Entity Framework Core Mistakes Slowing Down Your Application
👉 For .NET developers and backend engineers investigating database performance

https://bool.dev/blog/detail/ef-core-performance-mistakes
Clean LINQ can conceal expensive database behavior: loading unnecessary columns, issuing queries for every navigation access, or multiplying rows through collection joins. This guide connects common mistakes to concrete changes, including projections, bounded results, keyset pagination, and set-based updates.
The useful starting point is generated SQL, round-trip counts, and query plans, rather than framework tuning. Fixes also interact: eager loading can eliminate N+1 queries while producing a much larger result; split queries reduce duplication but add round trips and buffering. Measure both against realistic data and network latency. Pooling and compiled queries belong later, once the dominant cost is understood.
7 Patterns for Migrating Microservices to a Monolith
👉 For software architects and tech leads simplifying tightly coupled services
https://bool.dev/blog/detail/microservices-to-monolith

Services that share ownership, release schedules, and scaling requirements may pay the operational cost of distribution without gaining meaningful independence. This guide describes a gradual consolidation: align dependencies, capture existing behavior, redirect endpoints, replace network clients behind stable interfaces, and migrate data last.
The important distinction is between removing deployment boundaries and abandoning module boundaries. Moving calls into one process makes accidental coupling easier, so architectural checks must replace some of the separation the network previously enforced. Consolidation also concentrates failure and resource contention. Merge selectively, preserve genuine security or scaling boundaries, and avoid turning a deployment simplification into an irreversible database rewrite.
Node.js at scale, rebalanced: how we cut cost by 38%
👉 For platform engineers running Node.js and server-side rendering

https://medium.com/booking-com-development/node-js-at-scale-rebalanced-how-we-cut-cost-by-38-62ce247a3002
Booking.com reduced compute costs for its largest Node.js service by 38% through worker threads, explicit worker-level load balancing, separating heavy renders from lightweight requests, and garbage-collection tuning.
The revealing moment came when production contradicted synthetic benchmarks. Connection reuse interacted with kernel load distribution, repeatedly directing work toward particular workers. Pod-level averages concealed the imbalance; per-worker inspection exposed it. The practical lesson is to measure where requests actually wait, compare equivalent production deployments, and reduce capacity gradually while retaining headroom. Switching process managers was only one part of the improvement, not a standalone recipe for the same savings elsewhere.
Scaling Spark and Flink Shuffle at LinkedIn with Apache Celeborn
👉 For data-platform engineers operating distributed processing workloads

https://www.linkedin.com/blog/engineering/infrastructure/scaling-spark-and-flink-shuffle-at-linkedin-with-apache-celeborn
LinkedIn moved shuffle data into dedicated Apache Celeborn workers instead of tying it to compute hosts. Replication, topology-aware placement, and maintenance-aware draining help intermediate results survive failures. Compared with its Spark Magnet baseline, LinkedIn reports roughly 10% lower compute consumption and 14% shorter application runtime.
The architectural benefit is separating intermediate data lifetimes from the machines doing the computation. Losing a worker doesn't require recreating its output. That comes with a new responsibility: the shared shuffle service needs capacity planning, tenant isolation, and reliable operations. Evaluate the cost of failed work and recomputation alongside storage and network costs before adopting another distributed subsystem.