Back to blog
15 min read

How to Identify Blockers in Software Development Before They Derail Your Sprint

Most development blockers are visible before they cause damage — the signals are already in your GitHub history, Linear board, and ticket aging data. This guide walks startup dev teams through a practical, repeatable process for identifying blockers early, distinguishing them from slowdowns, and using engineering intelligence to surface issues automatically before they derail a sprint.

How to Identify Blockers in Software Development Before They Derail Your Sprint

Blockers are the silent killers of engineering velocity. A single stalled pull request, an unclear dependency, or an unresolved cross-team question can quietly consume days before anyone surfaces it in standup. For startup dev teams especially, where every sprint counts and headcount is lean, blockers compound fast.

The frustrating part? Most blockers are visible before they become damage. The signals are there in your GitHub history, your Linear board, your ticket aging data. The problem is that most teams only look when someone raises their hand, and by then, a day or more is already gone.

This guide walks you through a practical, repeatable process for identifying blockers early, understanding their root causes, and building the visibility your team needs to stay unblocked. We'll cover how to read the signals that precede a blocker, where to look in your existing tooling, how to distinguish a blocker from a slowdown, and how to use engineering intelligence to surface issues automatically rather than waiting for someone to speak up in standup.

This isn't about micromanaging your developers or adding process overhead. It's about building the right visibility so that blockers become visible before they become damage. Whether you're managing a team of five or fifty, the system works the same way: define clearly, detect early, triage fast, and close the loop.

Let's build that system step by step.

Step 1: Define What a Blocker Actually Is for Your Team

Before you can detect blockers reliably, you need a shared definition. This sounds obvious, but it's where most teams quietly fail. Without a clear, agreed-upon definition, developers under-report blockers (because they don't want to look stuck), managers over-identify them (because any slowdown feels like a problem), and the signal becomes noise.

Start with the core distinction: a true blocker is work that cannot proceed without external resolution. A slowdown is work that is hard, unclear, or uncomfortable, but still possible to move forward on. This distinction matters because the response is completely different. Blockers require escalation or coordination. Slowdowns require support, clarification, or a different approach.

Common blocker categories your team should recognize and name:

Dependency blockers: Work is waiting on another ticket, service, or team to deliver something first. The blocker is external to the developer.

Review bottlenecks: A pull request is ready but hasn't received a review within your expected window. The developer is done; the process is stuck.

Environment and infrastructure issues: A broken staging environment, a misconfigured CI pipeline, or missing credentials that prevent testing or deployment.

Unclear requirements: The ticket doesn't have enough detail to implement correctly, and the developer doesn't have a clear path to get that clarity quickly.

Cross-team dependencies: Work requires input, approval, or a deliverable from another team that hasn't been scheduled or committed to.

Once you have categories, set a time threshold. If work hasn't moved in a defined period, it's a blocker by definition regardless of how it's labeled. Many teams use 24 hours as the threshold for individual tickets and 48 hours for cross-team dependencies. Pick a number that fits your sprint cadence and stick to it.

One important pitfall to address directly: teams often misclassify "I haven't started yet" as a blocker. Not starting is a prioritization issue, not a blocker. A ticket that's in the backlog because it hasn't been picked up yet is not blocked. A ticket that's in progress but can't advance is blocked. Keep that distinction sharp, and your blocker data will actually mean something.

Step 2: Map Your Existing Signal Sources

Here's the thing most teams get wrong: they think they need new tools to detect blockers. They don't. The signals are almost certainly already there in the tools you're using every day. Step 2 is about reading what you already have before adding anything new.

Start by auditing where your work-in-progress data actually lives. For most startup dev teams, it's spread across a few places:

GitHub pull request age: This is one of the strongest leading indicators of a review bottleneck. Every PR has a timestamp. If your team's typical review window is 4 hours and a PR has been open for 36, that's a signal worth investigating. You don't need a special tool to see this, it's right there in your repository.

Linear ticket status and aging: A ticket that's been sitting in "In Progress" for two days without any new commits, comments, or status changes is a stall. Linear shows you when tickets were last updated. That data is your canary in the coal mine.

Standup notes and async updates: This is where blocker language often appears first, buried in a message like "still waiting on the API team" or "can't test until staging is fixed." The problem is that these updates are rarely aggregated or acted on systematically. They live in Slack threads, Notion docs, or meeting notes and then disappear.

Commit history: A developer who was committing daily and has gone quiet for two days is a signal. It doesn't mean something is wrong, but it's worth a quick check.

The action here is simple: make a list of where your work-in-progress data lives. GitHub, Linear, Slack, wherever your team documents progress. Then identify which of those sources you're actually reviewing regularly versus which ones you only look at when something has already gone wrong.

Most teams discover that they have plenty of signal. What they lack is a consistent habit of reading it. That's what the next step addresses.

Step 3: Establish a Cadence for Proactive Blocker Detection

The biggest structural problem with how most teams handle blockers is that they rely on developers to self-report. Standup becomes the primary detection mechanism, which means blockers surface reactively. By the time someone says "I'm blocked on X" in standup, they've often been blocked since the previous afternoon. That's a half-day or more of lost momentum before anyone even knows there's a problem.

The fix is to shift from reactive reporting to proactive scanning. Build detection into your process so that you're looking for blockers before they're raised, not after.

A practical cadence looks like this:

Daily async check (15 minutes, before standup): Review PRs open beyond your defined review window. Review tickets in "In Progress" with no activity in the past 24 hours. Flag anything that meets your blocker threshold and bring it to standup with context, not as a discovery, but as a confirmation or resolution.

Weekly engineering health review (30-45 minutes): Step back from individual tickets and look at work-stream health across your initiatives. Which epics or projects have stalled tickets? Which cross-team dependencies haven't moved? Where is work piling up versus flowing through? This is the level where systemic blockers become visible.

Define your escalation triggers clearly. What age of stall warrants an async nudge versus a synchronous conversation? A ticket stalled for 12 hours might just need a quick Slack message. A ticket stalled for 48 hours with a cross-team dependency probably needs a scheduled call. Having these triggers defined in advance removes the judgment call in the moment and makes the process consistent.

The pitfall to avoid here is treating daily standup as your primary detection system. Standup is valuable for coordination, but it's a lagging indicator of blockers, not a leading one. Proactive scanning before standup means you walk into that meeting with visibility, not questions.

Step 4: Read the Patterns That Precede Blockers

Blockers rarely appear without warning. There are almost always precursor signals in the days before a developer gets fully stuck. Learning to read those patterns is what separates teams that catch blockers early from teams that discover them in retrospective.

Here are the patterns worth watching:

Code churn without merging: When a developer is repeatedly editing the same files across multiple commits without merging, it often indicates confusion about requirements or a technical direction that keeps changing. This isn't always a blocker yet, but it's a signal that something is unclear. Catching it early means a quick conversation now instead of a stalled PR later.

Review load imbalance: If one senior developer is the designated reviewer for most of your PRs, you've created a single point of failure. When that person is heads-down on their own work, in meetings, or out sick, reviews stack up. This is a structural blocker pattern that shows up as PR aging across multiple tickets simultaneously. Look at who is reviewing what and whether the load is distributed.

Momentum drops: A developer who normally ships commits daily going quiet for a day or two is worth a low-key check-in. Not a performance conversation, just a "how's that ticket going, anything you need?" Often the answer is nothing, but occasionally you'll surface a blocker the developer hadn't flagged yet because they were still trying to solve it themselves.

Cross-team dependency tickets that haven't moved: Any ticket that references another team's work and hasn't had an update in 48 hours is high-risk. Cross-team dependencies are the hardest blockers to resolve because ownership is ambiguous. The earlier you identify them, the more runway you have to escalate.

Deployment pressure before release windows: High merge volume in the days before a release creates review bottlenecks almost mechanically. Reviewers get overwhelmed, PRs age, and suddenly you're in a crunch. Watch for this pattern in the lead-up to planned releases and redistribute review load proactively.

Tools like Progress surface these patterns automatically as pre-computed signals, flagging stalled work, review bottlenecks, and momentum shifts without requiring you to manually dig through GitHub and Linear every morning. But even before you have automated tooling, knowing what patterns to look for changes what you see.

Step 5: Triage and Categorize Blockers by Type and Urgency

Not all blockers need the same response. One of the fastest ways to burn out an engineering manager and create alert fatigue across the team is to treat every blocker as equally urgent. Triage is what keeps your blocker detection system from becoming noise.

A simple four-category framework works well for most startup dev teams:

Category 1: Internal blockers (review delays, unclear scope). These are resolved within the team, typically the same day. The owner is the engineering manager or tech lead. Response: direct message the reviewer, clarify the ticket, reassign if needed. SLA: same business day.

Category 2: Cross-team dependency blockers. These require escalation to another team lead or product owner. The key here is setting a clear SLA with the other team and following up on it. Don't assume the other team knows it's blocking you. Make it explicit. SLA: resolution or commitment within 24 hours of escalation.

Category 3: Infrastructure and environment blockers. Route these to your platform or DevOps function and track them separately from feature work. These blockers have a different resolution path and often affect multiple developers simultaneously. SLA: depends on severity, but broken staging environments should be treated as high priority because they block everyone.

Category 4: External blockers (third-party APIs, vendor issues). These require escalation to management and communication to stakeholders. They're often outside your control to resolve directly, so the focus shifts to workarounds and timeline communication. SLA: immediate escalation, ongoing status updates.

Create a simple triage matrix: Type x Urgency x Owner. This doesn't need to be a sophisticated tool. A shared doc or a tagged column in Linear works fine. What matters is that every identified blocker has a type, an urgency level, and a named owner who is responsible for unblocking, not just a note that someone is blocked.

The pitfall here is treating all blockers as equal urgency. When everything is urgent, nothing is. Triage protects your team's attention and ensures the highest-impact blockers get resolved first.

Step 6: Build a Resolution Loop, Not Just a Detection System

Detection without resolution is visibility theater. You can have the most sophisticated blocker identification system in the world, but if blockers aren't actually getting resolved faster as a result, you've just added process overhead without improving outcomes. The goal is a closed loop: detect, assign, resolve, learn.

The first requirement for closing the loop is explicit ownership. Every blocker needs a named owner who is responsible for unblocking, not just a note that a developer is stuck. "The team is aware" is not ownership. "Sarah is coordinating with the platform team and will have an update by 3pm" is ownership. The difference in resolution speed is significant.

Set resolution SLAs by category and enforce them. Internal blockers should be resolved within 4 hours. Cross-team dependency blockers should have a resolution path within 24 hours of escalation. Infrastructure blockers affecting multiple developers should be treated as incidents with active status updates. When SLAs slip, that's a signal that your resolution process needs attention, not just your detection process.

Track blocker recurrence. If the same type of blocker appears repeatedly across sprints, it's a systemic issue, not a one-off. A review bottleneck that shows up every sprint is a signal that your review process or reviewer availability needs structural change. A recurring cross-team dependency that blocks the same initiative repeatedly is a signal that the dependency needs to be formalized, scheduled, or eliminated.

Use retrospectives to analyze blocker patterns over time. Which work streams are most frequently blocked? Which dependencies are chronic? Which categories of blocker take the longest to resolve? This retrospective data is what turns your blocker detection system from a reactive tool into a proactive one. You start anticipating where blockers will appear before they do.

One practical tip: log resolved blockers with root cause, even briefly. A one-line note in your tracking system about why a blocker occurred and how it was resolved becomes valuable pattern data over time. It's the difference between fixing the same problem repeatedly and actually preventing it.

Step 7: Automate Detection So Blockers Surface Without Manual Effort

Manual blocker detection doesn't scale. As your team grows, your initiative count grows, your PR volume grows, and the cognitive load of manually scanning for stalls becomes unsustainable. The answer is to automate the scanning and keep the judgment human. Let the system surface the signals; let your engineering manager decide what to do about them.

The starting point is connecting your existing tools to a platform that can monitor them continuously. If your team is already using GitHub and Linear, you have the raw data. What you need is a layer that ingests that data, tracks PR age and ticket status over time, and surfaces anomalies without you having to ask.

Progress is built specifically for this. It ingests data from Linear, GitHub, and similar tools and delivers pre-computed signals: stalled work, review bottlenecks, deployment risk based on merge volume and code churn, and team momentum shifts. Instead of building a custom dashboard and manually checking it every morning, you get assessments that tell you where the risk is and what's stalling, so you act instead of dig.

The natural-language query capability changes how engineering managers interact with this data. Instead of building a filter in Linear or writing a GitHub search query, you can ask "what's stalled in the auth initiative?" or "which PRs have been open longest this week?" and get an answer grounded in real activity data. This is the MCP server and Claude integration that makes Progress genuinely different from dashboard-only tools.

Automated alerts are the other key capability. Configure alerts for tickets in "In Progress" beyond your defined threshold, PRs open beyond your review window, and work streams with no recent activity. These alerts replace the manual daily scan and ensure nothing slips through during busy periods.

For leadership, Progress generates executive summaries on demand. Engineering managers don't need to manually compile status reports. Leadership gets visibility into engineering health without requiring a meeting or a manual update cycle.

One important configuration note: automation surfaces everything, which means you need to set your signal thresholds carefully. If your alert threshold is too low, you'll generate noise that gets ignored. Start with thresholds slightly above your current typical review and ticket cycle times, then tighten them as you build confidence in the signal quality. The goal is meaningful alerts, not alert fatigue.

Your Blocker Detection System: A Quick-Reference Checklist

You now have a complete system, not just a checklist. Here's the seven-step summary you can keep visible during sprint planning and retrospectives:

1. Define your blockers: Agree on what a blocker is, categorize by type, and set a time threshold for automatic classification.

2. Map your signal sources: Audit where work-in-progress data lives in your existing tools before adding anything new.

3. Build a proactive cadence: Daily async scans before standup, weekly health reviews across initiatives, and defined escalation triggers.

4. Read precursor patterns: Code churn, review load imbalance, momentum drops, and cross-team ticket aging are all warnings before the blocker fully materializes.

5. Triage by type and urgency: Internal, cross-team, infrastructure, and external blockers each have different owners and SLAs.

6. Close the resolution loop: Assign explicit ownership, enforce SLAs, track recurrence, and log root causes for retrospective analysis.

7. Automate the scanning: Connect your tools to an engineering intelligence platform that surfaces stalls and bottlenecks continuously, so you act on signals instead of searching for them.

The shift this system represents is from reactive to proactive. Standup is a coordination tool, not a detection system. When blockers are already visible before standup begins, the meeting becomes about resolution rather than discovery. That's where velocity lives.

One thing worth saying clearly: this system is not about surveillance. It's about giving engineering leaders the visibility they need to remove obstacles quickly, so developers can stay in flow and teams can deliver consistently. The goal is always team unblocking speed, not monitoring individual output.

If you want to automate steps 2, 4, and 7 using data from your existing GitHub and Linear setup, Learn more about our services and see how Progress turns your raw development activity into clear, actionable signals your team can act on today.


Start your 7-day free trial

Try it on this week's work.

Connect your tools and Progress fills in your last two weeks, so you see what's moving and what's stuck from day one.

7-day free trial · cancel anytime