Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
158524 stories
·
33 followers

Should You Split That Into Microservices? Ask These 5 Questions First

1 Share

I've helped teams adopt microservices, and I've helped teams dig themselves out of microservices. The second group is bigger.

In almost every failure case, the decision to split came before the reasons did. The app might need to scale someday. The monolith feels messier every sprint. A conference talk made independent deployments look easy. None of those are reasons to take on a distributed system.

Meanwhile, the actual trade is brutal and specific: microservices exchange local complexity for distributed complexity. A method call becomes a network hop. A transaction becomes a saga. A stack trace becomes a distributed trace across three services and a queue.

The same feature as a method call in a monolith, versus a network call between two services with retries, an outbox, idempotency, and tracing

Sometimes that trade is worth it. I've made it myself, and I'd make it again in the right situation. The five questions below are how I find out. Answer them honestly and the decision usually makes itself.

1. Do Parts of the System Have Genuinely Different Scaling Needs?

I don't mean needs you might have someday. I mean needs you can measure today: one part of the system handles 100x the traffic of the rest, or needs a GPU, or eats memory in a way that forces you to size the whole deployment for its peak.

That's a real reason. Extracting a hot path so it can scale (and fail) independently is one of the best arguments for a service boundary.

Three monolith instances each duplicating a hot Search module, versus one monolith instance plus three copies of an extracted Search service

But check the honest version first: most .NET monoliths scale out fine behind a load balancer. If your whole app comfortably runs on three instances, you don't have a scaling problem worth a service boundary.

2. Are Teams Actually Blocking Each Other?

Microservices are an organizational tool as much as a technical one. The strongest version of this signal looks like: multiple teams, one codebase, and a release process where team A's half-finished feature delays team B's hotfix. Deploy trains, release freezes, merge queues that take a day.

Three teams

If that's your life, independent deployability has real value.

If you're a team of six, it isn't. One team doesn't step on itself hard enough to justify operating a distributed system. I'd go as far as saying: below roughly two full teams, the organizational argument for microservices is zero.

3. Can You Draw the Data Boundary?

This is the question that kills most splits, and it's the one people skip.

Each service must own its data outright. Owning it means no other service reads its tables directly, not even for one convenient join. If two candidate services constantly need each other's data to answer basic queries, they aren't two services. They're one service you're about to cut in half.

Two candidate services, each owning its database, with red cross-boundary queries between them: one service, cut in half

I learned this one the hard way, and wrote about it in the modular monolith boundary I couldn't take back: a boundary that looks clean on the org chart can be hopelessly entangled at the data level. The entanglement doesn't go away when you add a network between the halves. It gets worse, because now every "join" is an API call, and keeping the data boundaries intact becomes a distributed problem.

4. Does Anything Require Independent Failure or Release?

Some parts of a system carry requirements the rest doesn't:

  • A payment flow that must stay up even when the reporting module is down
  • A component with a compliance boundary (PCI, HIPAA) where you want the audited surface as small as possible
  • An integration that ships weekly while the core ships quarterly

These are legitimate isolation requirements, and a service boundary is a clean way to express them. Notice how specific they are. A general wish for isolation is not on the list.

The rest of the system with Reporting down in one dashed boundary, and a healthy Payments service isolated in its own, where the PCI scope stops

5. Can You Afford the Platform Tax?

Before the first microservice delivers any value, you need: a container platform, CI/CD per service, centralized logging, distributed tracing, a message broker, and the reliability patterns that make inter-service communication safe (outbox, idempotent consumers, retries with backoff).

That's the entry fee, paid in engineer-months, before benefit number one.

Iceberg: one microservice above the waterline, with the container platform, CI/CD, logging, tracing, broker, and reliability patterns below it

A team that can't spare that capacity doesn't get a cheaper version of microservices. It gets a distributed monolith with none of the benefits and all of the costs.

Scoring It

The rule I use:

  • Four or five yes answers: split, and start with one service, not twelve. Extract the piece with the clearest boundary and run it in production for a quarter before extracting the next.
  • Two or three: you want modules, not services. A modular monolith gives you the boundaries, the team ownership, and the option to split later, without the platform tax. The boundaries you enforce now are exactly what makes the eventual migration mechanical instead of heroic.
  • Zero or one: keep the monolith and invest the energy you just saved into making it excellent.
The five questions feed one decision: how many honest yes answers. Four or five means microservices, two or three a modular monolith, zero or one keep the monolith

The teams that regret microservices almost never got the technology wrong. They got this checklist wrong, eighteen months earlier, in the meeting where the split was decided before the reasons existed. Run the five questions before your version of that meeting.

Thanks for reading.

And stay awesome!




Read the whole story
alvinashcraft
58 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Free Book Chapters, Better Testing Control, and Smart MCP Configuration!

1 Share

The learning resources this week are incredible! From free textbook chapters on advanced Angular topics to precision timing controls in your Vitest test suites, our community experts are sharing massive value to help you optimize your apps and your workflows.

Dive into these fantastic technical resources:

Three Free Online Chapters for Advanced Angular
Johannes Hoppe (@johanneshoppe), Ferdinand Malcher (@fmalcher01), and Danny Koppenhagen are offering a sneak peek into their upcoming book! They have released three highly detailed, free online chapters covering critical architectural pillars: Interceptors, Localization/Internationalization (i18n), and Server-Side Rendering (SSR).

Mini TypeScript Hero: A Sleek VS Code Extension
Clean up your workspace! Johannes Hoppe (@johanneshoppe) introduces a handy development utility designed to keep your imports tidy and organized without the bloat, making your daily coding experience much smoother.

MCP Skills vs. MCP Tools: Configuring Your Server Correctly
Antonio Cardenas (@yeoudev) delivers a vital architectural distinction for AI-driven workflows. Learn the right way to configure your Model Context Protocol (MCP) server, mapping out how to structure “skills” versus “tools” for maximum AI efficiency.

Precise Time Control & Instant Timer Skips in Tests
Younes Jaaidi (@yjaaidi) drops two brilliant guides on handling asynchronous behavior in your test suites. Learn the core fundamentals of controlling time, and discover how Vitest’s new “Fast-Forward” mode skips right past timer delays instantly.

Test Components Like a Real User with Vitest “Full” Browser Mode
Younes Jaaidi (@yjaaidi) also shares an excellent video walkthrough demonstrating how to use Vitest’s Full Browser Mode to evaluate your Angular components in a genuine rendering environment.

Have you tried Vitest’s new fast-forward modes, or are you optimizing an MCP setup for your team? Let us know how these modern tools are changing your development speed!

Keep the knowledge spreading! Use #AngularSparkles to highlight and share these awesome community tutorials today! 👇


Free Book Chapters, Better Testing Control, and Smart MCP Configuration! 📚🧪 was originally published in Angular Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.

Read the whole story
alvinashcraft
58 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Enable on-demand expertise with Agent Skills in Genkit Go

1 Share
To prevent context window bloat and reduce token consumption, Genkit Go introduces Agent Skills based on a progressive disclosure architecture. Developers can package specialized instructions, scripts, and references into modular SKILL.md bundles where only the frontmatter metadata is initially exposed to the agent's system prompt. When a task matches the skill's description, Genkit's middleware dynamically loads the full instruction body and associated assets, ensuring the model accesses precise workflows exactly when needed.
Read the whole story
alvinashcraft
58 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Kubernetes v1.37 Sneak Peek

1 Share

As we get closer to the release date for Kubernetes v1.37, the project develops and matures, features may be deprecated, removed, or replaced with better ones for the project's overall health. This blog outlines some of the planned changes for the Kubernetes v1.37 release that the release team feels you should be aware of for the continued maintenance of your Kubernetes environment and keeping up to date with the latest changes. The information below reflects the current status of the v1.37 release and may change before the actual release date.

Deprecations and removals for Kubernetes v1.37

Kubectl: kubectl run --filename/-f to be deprecated

The --filename (or -f) flag for kubectl run is being deprecated as the generated pod is always built purely from CLI arguments like NAME and --image.

See kubernetes/kubernetes#138671 for the original issue and discussion.

Kubelet: Static Pods can no longer reference Secrets or ConfigMaps

Static Pods were never meant to read API resources directly, since they aren't created through the API server — but a bug let them reference Secrets or ConfigMaps via fields like configMapRef or secretRef. That bug is now fixed: as of v1.37 these references are strictly prohibited, and the PreventStaticPodAPIReferences feature gate that previously let you opt out of the restriction has been removed.

See kubernetes/kubernetes#140226 for the original issue and discussion.

Deprecating kube-proxy's support for ipvs mode

kube-proxy support for ipvs mode was introduced in v1.8 to resolve iptables performance bottlenecks. However, since the kernel ipvs API alone cannot fully implement Kubernetes Services, ipvs mode continues to use iptables underneath (KEP-3866, "The ipvs mode of kube-proxy will not save us").

Clusters running kube-proxy in ipvs mode (or mode: ipvs in KubeProxyConfiguration) would now be logging a deprecation warning on startup. The deprecation timeline looks like this:

  • By v1.40, ipvs mode for kube-proxy is expected to be disabled by default (still selectable via the feature gate)
  • By v1.43, support for ipvs mode would be removed entirely KEP-5495, Graduation Criteria. To confirm which mode you’re currently running, use:
kubectl -n kube-system get configmap kube-proxy -o jsonpath='{.data.config\.conf}' | grep 'mode:'

To understand the rationale behind this deprecation, see KEP-5495: Deprecate ipvs mode in kube-proxy.

Future removal of cgroup v1 support

As modern Linux distributions and container runtimes use cgroup v2 as the default, support for the legacy cgroup v1 is officially being phased out. Since the v1.35 release, the failCgroupV1 setting has defaulted to true. Consequently, the kubelet will fail to initialize on any nodes that still rely on cgroup v1 unless an explicit configuration override is applied.

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
failCgroupV1: false # temporary override

Using this override should be considered a short-term fix. Advanced resource management capabilities, such as In-Place Pod Resizing and Tiered Memory Protection, depend entirely on cgroup v2. While the override remains available in Kubernetes v1.37, users are encouraged to migrate to cgroup v2, as support for cgroup v1 is planned to be removed in a future release.

To learn more about this deprecation, refer to KEP-5573: Remove cgroup v1 support.

Breaking changes in Kubernetes v1.37

SELinux volume relabeling ("SELinuxMount") graduates to GA

SELinuxMount is expected to reach GA and be enabled by default in v1.37. Volumes would then be mounted with -o context=<label> (the mount option default) instead of being recursively relabeled, but only when the volume's CSI driver opts in via a CSIDriver that sets .spec seLinuxMount: true.

Because a single mount can only hold one SELinux context, pods with different SELinux labels sharing a volume on the same node (which previously coexisted under recursive relabeling) may now fail to start. To retain the previous recursive behavior for a specific workload, set seLinuxChangePolicy: Recursive in the Pod spec.

Clusters without SELinux enabled see no effect at all. To learn more, check SELinux Volume Label Changes goes GA (and likely implications in v1.37)

Metrics API goes GA

The metrics.k8s.io API is expected to graduate to Stable (GA) in Kubernetes v1.37 after spending nearly nine years in Beta. The API provides a standard way to retrieve CPU and memory usage for pods and nodes, powering widely used Kubernetes features such as the Horizontal Pod Autoscaler (HPA) and commands like kubectl top.

This graduation recognizes the API's stability and widespread adoption, with no functional changes expected. Both v1 and v1beta1 will remain usable during the transition, enabling developers to adopt the stable API at their own pace without breaking existing workflows.

To learn more about this enhancement, refer to KEP-5207: metrics.k8s.io API definition.

Kubelet in UserNS a.k.a. Rootless Mode

Traditionally, Kubernetes node components such as the kubelet run with root privileges on the host. While necessary for many deployments, this also means that a vulnerability in one of these components could potentially have a greater impact on the underlying system.

With Kubernetes v1.37, kubelet in User Namespace (Rootless Mode) is expected to graduate to Beta. This enhancement allows Kubernetes node components to run inside a Linux user namespace as an unprivileged user on the host while still behaving as root within the namespace. By reducing the need for host-level root privileges, it adds an extra layer of isolation and helps limit the impact of potential vulnerabilities affecting node components.

To learn more about this enhancement, refer to KEP-2033: Kubelet in UserNS(aka Rootless Mode).

Volume health monitor

Historically, Kubernetes has lacked an API for CSI drivers to report storage failures, which become evident only through failed mounts or hung I/O. Since remediation controllers had nothing machine-readable to act upon, the only way to figure out the root cause behind this failure was to cross-reference Kubernetes objects alongside external vendor dashboards.

In Kubernetes v1.37, this KEP resets graduation to Alpha after an initial implementation in v1.21 and introduces four new CSI RPCs. The controller plugin reports the health of storage volumes using ControllerListVolumeHealth (lists unhealthy volumes) and ControllerGetVolumeHealth (checks a specific volume). A controller-side health monitor polls these CSI controllers and stores the results in PersistentVolumeClaim.status.healthStatus.

On the node side, the kubelet calls NodeGetVolumeHealth to obtain the health of individual volumes on that node and records it in Pod.status.volumeHealth, while NodeGetStorageHealth reports the health of the drivers registered to a node in CSINode.status.storageHealth.

The error vocabulary is kept simple, extensible, and machine-parsable (Inaccessible, Degraded, etc.), with further driver-specific elaboration available via reason and message. Finally, the controller-side and node-side reports are kept independent and are hence displayed separately, providing a more holistic view of storage health to consumers.

To learn more about this enhancement, refer to KEP-1432: Volume Health Monitor.

Want to know more?

New features and deprecations are also announced in the Kubernetes release notes. We will formally announce what's new in Kubernetes v1.37 as part of the CHANGELOG for that release.

Kubernetes v1.37 release is planned for Wednesday, August 26th, 2026. Stay tuned for updates!

You can see the announcements of changes in the release notes for:

Get involved

The simplest way to get involved with Kubernetes is by joining one of the many Special Interest Groups (SIGs) that align with your interests.

If you don't know where to start, join our monthly New Contributor Orientations where we teach the community how the project is structured, and we'll guide you on how to make your first contribution to the project.

Read the whole story
alvinashcraft
59 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Docker OIDC connections for GitHub Actions available for Docker Orgs

1 Share
Eliminate Stored Credentials in Your CI/CD Pipelines

TL;DR: Docker now supports OpenID Connect (OIDC) for GitHub Actions. Your workflows can authenticate with short-lived, per-run tokens instead of stored PATs or OATs. No secrets to rotate, no credentials to leak. 

GitHub OIDC connections are available to organizations with Docker Team, Docker Business, or Docker Hardened Images (DHI) subscriptions, as well as organizations enrolled in the Docker Sponsored Open Source Program (DSOS).

Table of contents

  • The problem with stored credentials
  • Who should use this
  • How OIDC connections work
  • Getting started
  • What doesn’t change
  • Learn more

OIDC token exchange flow between GitHub Actions and Docker

diagram final

The problem with stored credentials

Every GitHub Actions workflow that pushes or pulls images from Docker Hub authenticates with a personal access token (PAT) or organization access token (OAT) stored as a GitHub secret. These credentials are long-lived. Someone has to remember to rotate them. A leaked token grants access to your registry — pulling private images, pushing malicious ones — and that access persists until someone discovers and revokes it. Rotation is manual and does not scale. As pipelines multiply, so do the credentials that need tracking, and stale tokens are a common audit finding.

Who should use this

  1. GitHub issues a signed identity token (a JWT) that encodes the repository, branch, environment, and other metadata about the workflow run.
  2. The workflow calls docker/login-action, which presents this token to Docker.
  3. Docker verifies the token’s signature against GitHub’s public key registry and checks it against rulesets configured in the Admin Console.
  4. If the token matches a ruleset, Docker returns a short-lived access token scoped to the resources defined in that ruleset.
  5. docker/login-action uses this token to authenticate to Docker Hub. From there, docker pull, docker push, and docker build commands work as usual.

The entire exchange happens without any stored secrets, API keys, or access tokens. The short-lived Docker access token expires in minutes and cannot be reused.

This is the same pattern that AWS and GCP already use for cloud resource access (AWS OIDC for GitHub Actions, GCP Workload Identity Federation). Docker is applying it to container registry access.

Getting started

Setup is a one-time connection in Docker Home plus a small update to your workflow YAML.

Step 1: Create a connection

Sign in to Docker Home, select your organization, and navigate to OIDC connections. Select Create OIDC connection and configure the rulesets that control which repositories, branches, and workflows can access which Docker Hub resources. You can create up to five rulesets per connection. When a workflow triggers an OIDC exchange, Docker checks the token against every ruleset defined in your connection. If a ruleset’s conditions are satisfied, Docker grants access based on the parameters set by that ruleset.

Rulesets use OIDC subject claims to match incoming tokens. You can pin to specific repos and branches as a recommended security best practice:

  • repo:my-org/my-repo:ref:refs/heads/main — only the main branch of a specific repo
  • repo:my-org/my-repo:ref:refs/heads/release-* — all release branches
  • repo:my-org/my-repo:* – all branches of this repo
  • repo:my-org/* — any repo in the organization (not recommended)

Copy the connection ID when you are done.

Note: GitHub repositories created after July 15, 2026 use immutable identifiers for default subject claims. For example: repo:octocat@123456/my-repo@456789:ref:refs/heads/main. See the GitHub changelog for more details.

Step 2: Update your workflow

Update your GitHub Actions workflow. Replace <YOUR_CONNECTION_ID> with the ID from the previous step and <YOUR_ORG_NAME> with your Docker organization name:

permissions:
  contents: read
  id-token: write

steps:
    - name: Docker login                                                                                                                                                                 
      uses: docker/login-action@v4 # v4.5.0+                                                                                                                                                                
      with:                           
        username: <YOUR_ORG_NAME>
      env:                                                                                                                                                                               
        DOCKERHUB_OIDC_CONNECTIONID: <YOUR_CONNECTION_ID>

The id-token: write permission lets the workflow request a GitHub OIDC token. The docker/login-action handles the token exchange and Docker login in a single step when DOCKERHUB_OIDC_CONNECTIONID is set. From there, docker pull, docker push, and docker build commands work as usual.details of the incoming claim sub value, which you can use to diagnose why the connection failed.

Step 3: Verify the OIDC connection works

Run your workflow and confirm it completes successfully. If you encounter an error, the Failures tab of the OIDC connection page will show the details of the incoming claim sub value, which you can use to diagnose why the connection failed.

Step 4: Remove the stored credential

After verifying your workflow runs successfully with OIDC, remove the old PAT or OAT from your GitHub repository secrets. You no longer need it.

Migration Checklist

  • Create a connection
  • Update your workflow
  • Verify the OIDC connection works
  • Remove stored credentials

What doesn’t change

  • Existing PATs and OATs keep working. Organizations can migrate workflows to OIDC connections at their own pace.
  • Images, registries, and build workflows are unchanged. OIDC connections only replace the authentication step; everything downstream is the same.
  • Local development and non-GitHub CI still use PATs and OATs. OIDC connections are the recommended replacement for GitHub Actions specifically. Other CI providers will follow based on demand.

Learn more

Read the whole story
alvinashcraft
59 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Agent and Model Evaluations in Gemini Enterprise Agent Platform are now GA

1 Share
Agent Platform's evaluation service is now generally available, providing developers with a unified engine to measure agent quality consistently across local development experiments and live production traffic. You can evaluate agents using over 20 pre-built metrics, DeepMind-backed adaptive rubrics, or custom code-based and LLM-as-a-judge metrics stored in a centralized, versioned registry. The service integrates directly into existing workflows via the Agent Platform SDK, agents-cli, and ADK, offering built-in user and environment simulators to automate complex multi-turn testing and streamline CI pipelines.
Read the whole story
alvinashcraft
59 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories