Query icon
Log icon
If icon
SlackIncomingWebhook icon
Pause icon
Fail icon
Schedule icon

Neo4j Long-Running Transaction Killer Guard

Find Neo4j transactions over an elapsed-time threshold, alert Slack, terminate them after approval, then verify none of the targeted ones is still open.

Categories
DataInfrastructure

A single transaction that runs for too long is a real operational problem in Neo4j. It holds locks that block other writers. It pins memory and page cache. A forgotten BEGIN from a client that never committed can sit open for hours. Neo4j will not end it for you. Someone has to see it and terminate it.

This blueprint lists the live transactions, keeps the ones whose elapsed time is at or over a threshold you set and reports them to Slack. When you turn remediation on and a human approves, it terminates those transactions, waits a moment, lists the transactions again and fails the run if any transaction it targeted is still open. It never terminates its own session, because the audit and kill statements are excluded by their query text and it never touches a username you choose to protect.

This blueprint was created by zkasuran.

Safety

Terminating a transaction rolls back its work and frees its locks, which is disruptive on purpose. Two independent inputs (auto_remediate and dry_run) and a manual Pause sit between a finding and any kill, so the default run only reports. The exclude_users input keeps named service or admin accounts off the kill list. The guard excludes its own SHOW TRANSACTIONS and TERMINATE TRANSACTIONS statements by query text, so it can never terminate itself.

How it works

  1. audit (io.kestra.plugin.neo4j.Query, read-only, storeType: FETCH) runs SHOW TRANSACTIONS ... WHERE elapsedTime.milliseconds >= threshold. It drops its own statements by query text and drops any excluded username, then returns the transaction id, elapsed milliseconds, status, username and a trimmed current query, worst first.
  2. summary logs every transaction it found.
  3. route (io.kestra.plugin.core.flow.If on outputs.audit.size > 0):
    • clean: clean logs that nothing is over the threshold.
    • findings: alert posts the count and the worst offender to Slack, saying whether it is about to terminate.
      • remediate_gate runs only when auto_remediate is true and dry_run is false.
      • approve is a Pause. A human resumes it with approved true to go ahead or false to stop.
      • apply_gate runs the kill only when approved is true.
      • kill (io.kestra.plugin.neo4j.Query, allowFailure: true) re-lists and terminates in one statement, so the filter is fresh at kill time. TERMINATE TRANSACTIONS returns one row per id, so the task is allowed to fail and the re-list is the real gate.
      • settle waits five seconds for the rollbacks to clear.
      • reaudit lists the transactions again. verify_result fails the run if any id the audit targeted is still open.
  4. errors alerts Slack when the flow itself fails, for example an unreachable instance or bad credentials, so a failed audit is never read as "nothing wrong".

What you get

  • A direct list of the transactions Neo4j is actually running past your threshold, from its own SHOW TRANSACTIONS, with the owning user and the current query.
  • A terminate step that re-checks the filter at kill time rather than trusting a stale snapshot.
  • A guard that cannot terminate its own session and leaves any excluded user alone.
  • Two inputs plus a manual approval between a finding and any kill.
  • Proof the fix landed: the run fails loudly if a targeted transaction is still open after the terminate, so a transaction that refuses to roll back is surfaced rather than hidden.

Who it's for

  • Teams running Neo4j that have had a writer blocked by one forgotten open transaction.
  • Platform and data engineers who want a scheduled, approved way to clear runaway or leaked transactions instead of doing it by hand at 2am.
  • Anyone evaluating the Neo4j plugin who wants a worked example of Query driving SHOW TRANSACTIONS and TERMINATE TRANSACTIONS with a verify step.

Why orchestrate this with Kestra

Spotting a long transaction is one query. Clearing it safely is a sequence: capture the offenders, get a human to approve, terminate, wait for the rollback, then check the result and fail if it did not take. Kestra runs that sequence on a schedule behind two gates and an approval. It keeps protected users and the guard own session out of it, alerts Slack on both the finding and a failure and keeps a history of what was terminated and where.

Tested end to end

On Kestra 2.0.5 OSS against Neo4j 5.26 Community, with a local HTTP sink standing in for Slack. A long-running transaction was produced for real by running UNWIND range(1,1000000000) AS x RETURN count(x) from a side cypher-shell session, which holds one transaction open for over two minutes. cypher-shell confirmed the transaction id and its elapsed time before and after every run.

Run Inputs Result
1 defaults, no long transaction 0 found, clean logged. No alert
2 threshold_seconds: 3, one long transaction 1 reported, alert sent. No change. cypher-shell shows it still running
3 auto_remediate: true, dry_run: true Same report, kill held. The transaction is untouched
4 auto_remediate: true, dry_run: false, approved false Report, approve resumed with false, no kill. The transaction survives
5 auto_remediate: true, dry_run: false, approved true Terminated. settle waited, reaudit clean, verify_result passed. cypher-shell shows the transaction gone
6 unreachable URL audit failed, errors alert sent

Exact execution ids and the before and after transaction counts are in the pull request notes.

Prerequisites

  • A reachable Neo4j 5.x instance. SHOW TRANSACTIONS and TERMINATE TRANSACTIONS are Cypher administration commands available on Community and Enterprise.
  • For the audit, a user that can run SHOW TRANSACTIONS. For remediation, a user allowed to TERMINATE TRANSACTIONS.
  • A Slack incoming webhook for alerts.
  • Local testing:
    • docker run -d --name neo4j -p 7687:7687 -e NEO4J_AUTH=neo4j/testpassword neo4j:5;
    • open a long transaction from another shell: cypher-shell -u neo4j -p testpassword "UNWIND range(1,1000000000) AS x RETURN count(x);" and run the flow with threshold_seconds set low.

Secrets

  • NEO4J_PASSWORD: password for the Neo4j user, the default for the password input.
  • SLACK_WEBHOOK_URL: Slack incoming webhook used by alert and the errors block.
  • In Kestra OSS, provide each one as a base64-encoded environment variable prefixed SECRET_, for example SECRET_NEO4J_PASSWORD=$(echo -n 'testpassword' | base64).

Inputs

Input Default Purpose
url bolt://localhost:7687 Bolt endpoint
user neo4j Neo4j user
password {{ secret('NEO4J_PASSWORD') }} Password, from the secret by default
threshold_seconds 120 Elapsed time at or over which a transaction is long running
exclude_users empty Comma-separated usernames never terminated
auto_remediate false Allow terminate
dry_run true Must be false for any terminate to run

Quick start

  1. Add the NEO4J_PASSWORD and SLACK_WEBHOOK_URL secrets.
  2. Import the flow and set url and user.
  3. Run it once with the defaults and read the transactions over the threshold.
  4. Decide a sensible threshold_seconds for your workload, since legitimate bulk writes can be long.
  5. Add any service accounts to exclude_users so they are never terminated.
  6. Run it with auto_remediate: true and dry_run: false, approve the Pause, then the offenders are terminated and verified.
  7. Enable the daily trigger, which always runs in safe mode.

How to extend

  • Add a max_terminations cap so a single run never kills more than N transactions.
  • Alert only, by routing the finding to a ticket instead of terminating, for an advisory deployment.
  • Narrow the audit to one database in a multi-database setup or to transactions whose current query matches a pattern.
  • Treat a known long batch job as healthy by adding its username to exclude_users or filtering its query text.
  • Replace the elapsed-time threshold with a lock-wait or idle-time signal for a tighter definition of stuck.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.