A museum catalog publishes a nightly set of updated exhibit records. Sometimes a scheduled import and a staff-triggered correction begin at the same time. If both write to the same destination, objects may be duplicated or an older version may overwrite the newer one. GitHub Actions concurrency lets workflow authors constrain simultaneous jobs in a group. It does not guarantee successful imports, order by request time, or atomic external writes. This is a fictional release workflow illustrating how to combine serialization with real idempotency.
Write down the operation that must not overlap
First identify the shared resource: a production catalog index, a public JSON export, or a destination media bucket. Two test jobs that read separate input fixtures can usually run concurrently, whereas two imports updating the same collection may conflict. Decide which operations truly need serialization. Use a release key tied to the shared destination, not an arbitrary branch name that lets two different branches modify the same production database.
Record a stable catalog batch ID and manifest checksum before a workflow starts. That ID should be used by the destination to recognize a retried import, even when GitHub launches the workflow more than once. Concurrency helps schedule attempts but cannot determine whether a previous job committed half of its records before a runner failed. Build a reconciliation command for that uncertain state.
Understand running and pending group rules
GitHub documents workflow-level and job-level concurrency groups. By default, a group has at most one running and one pending execution; when another execution is queued in the same group, the newer pending job replaces the existing pending one. The order of group execution is not guaranteed. GitHub also documents an optional queue mode, so authors should check current support and configuration rather than assuming every request will be retained.

The cancel-in-progress setting controls whether a new group member can cancel a currently running job. A cancellation request is not a database rollback. If an import writes hundreds of catalog records, stopping the runner midstream may leave a partial state. For production imports, prefer safe retry and reconciliation over indiscriminately enabling cancellation. In contrast, a preview build without external writes may tolerate canceling superseded runs.
Choose a stable concurrency key
A job key such as catalog-production is useful when all jobs target one production catalog. If there are completely independent destinations, different group keys can allow parallel runs without collision. Keep names stable and unambiguous; GitHub treats group names case-insensitively. Use the documented expression contexts and do not interpolate untrusted user text into a key without validation.
When using job-level concurrency, ensure every job that can write to the same target participates in the intended group or is coordinated through the destination service. A separate manual maintenance script can bypass Actions entirely. Document the shared lock scope in repository policy, and show the key visually beside the production destination so reviewers can audit it. A branch-specific group is not sufficient if several branches deploy to the same endpoint.
Design a queue that preserves important corrections
Consider a scheduled run that is active, a curator correction pending, and then a second staff correction requested. Under default single-pending behavior, one pending request can be replaced. If every revision must be processed, use a source-of-truth queue or an appropriately supported queue mode, and still reconcile the latest approved state. Do not assume canceled pending workflows automatically send a warning to the curator.
A good system creates a release candidate from immutable approved input. A newly triggered job reads the latest approved manifest, not an arbitrary mutable folder. If a pending run is replaced, staff can check which input version was actually imported. Record the publication time from the catalog system, not just the Actions start time. The four-step process image highlights the queue and independent record reconciliation.
Compare overlap, serialization and complete release
In the first hypothetical state, two writers both attempt to update the same object, creating an obvious conflict risk. In the second, a concurrency group permits only one active writer; a later run waits or replaces the pending run according to policy. In the third, the destination validates object IDs and hashes before committing a revision. The figure does not depict real repository logs or guarantee that concurrency resolved all data problems.

Do not mark the final state approved merely because the second job completed with a green build. Compare imported object counts, revision IDs, checksum totals and a small sample of records against the approved manifest. A stale runner can succeed while publishing an old data snapshot. That is a semantic failure that concurrency cannot detect. Review the audit trail across repository, cloud destination and WordPress or catalog front end.
Make imports safe to retry
Design external writes to be idempotent: reprocessing the same release should produce the same catalog state rather than two records. Use stable object IDs, conditional updates or destination-side transactions where supported. Make a dry-run available that lists create, update and delete operations without applying them. Destructive deletions should need a separate approval gate.
A runner that loses network connectivity after an external POST might not know whether the request succeeded. Before retrying, query the destination for that release ID and reconcile applied objects. Avoid blindly replaying an import based only on an Actions failure badge. Keep credentials scoped to the destination and workflow. Locking, permissions, approval and deduplication solve different problems.
Test concurrency with synthetic collision cases
Build a test repository fixture with two jobs that both try to publish the same invented record. Trigger a scheduled-like run and a manual one close together. Observe running and pending states, cancellation behavior and log visibility. Also test a job interrupted after writing the first half of its data. The acceptance criterion is stable resulting state, not merely fewer overlapping runners.

Do not test interruption by making uncontrolled changes to the live museum catalog. Use a temporary destination and clearly tagged mock IDs. Confirm that CI artifacts include release ID, source checksum, destination revision and a human-readable diff. Since queue behavior can evolve, verify the exact GitHub Actions documentation and plan constraints at the time you ship the workflow.
Publish only after destination reconciliation
Add a final step that checks the actual catalog destination for expected revision and permissions. Notify staff when a pending correction is replaced or a partial import needs human intervention. Keep the last known good release for rollback, and avoid conflating repository build artifacts with the published public site. A successful CI run is an operational event, not a statement that all source material is approved for publication.
GitHub concurrency provides a useful scheduling boundary for shared writing jobs. It is not a distributed transaction manager, a permission system or a substitute for provenance. The most reliable process combines a narrow group key, intentionally chosen pending policy, idempotent destination writes and a reviewed release manifest. Those safeguards protect the public catalog even when the network or runner fails.
How We Research
For our November 2026 editorial review, we consulted the named official developer sources: GitHub Actions concurrency controls; GitHub Actions workflow syntax. We compared documented feature scope, request shapes, output limitations, and failure cases with a clearly hypothetical nonproduction museum or community-history scenario. We did not run paid API calls, process private recordings, access donor or visitor records, benchmark vendors, measure recognition accuracy, or capture actual product screenshots. All illustrations are original explanatory drawings rather than real output or proof of performance. Prices, availability, privacy terms, model support, and preview features can change; check the current official documentation and an authorized local test before deploying.
Frequently Asked Questions
No. GitHub does not guarantee execution order within a concurrency group.
The documented default allows one pending member per group, with newer pending work replacing the earlier pending job.
No. It stops execution but does not undo already applied external effects.
Yes. Use a shared production-destination group key rather than a branch-specific key when both write to the same resource.
A run may be retried or fail after some writes; destination reconciliation prevents duplicate or stale records.
