1.Five-minute setup
Assuming the plugin is installed and migrated, this is the shortest path from nothing to a tracked issue.
- 1
Create the calendars
Administration → SLA → Business calendars → Create default calendars. You get a 24×7 calendar plus Monday–Friday 09:00–18:00 calendars for UTC, India, the UK and US Eastern. Edit one or add your own.
- 2
Write a policy
Administration → SLA → SLA policies → New policy. Give it a first response target (
30m) and a resolution target (4h), pick a calendar, and leave the conditions empty for now so it applies to everything. - 3
Add pause rules
Administration → SLA → Pause rules. Add the status you use for “waiting on the customer” and tick Resolution and Closure — but not First response. Why.
- 4
Turn it on for a project
Project → Settings → Modules, tick SLA. Then Project → Settings → SLA and tick SLA enabled. Both are needed.
- 5
Schedule the background task
Without it, warnings and breaches are only noticed when somebody saves the issue. See Keeping it running.
Create an issue in that project. It should now show an SLA panel.
Enabling the plugin does not backfill. Issues raised before you switched it on stay without an SLA unless you deliberately backfill them — and because they would be measured from their original creation date, most would appear breached immediately.
2.How it thinks
Four ideas explain nearly every behaviour you will see.
- Policy
- The commitment: what the targets are, which calendar measures them, and which issues it applies to.
- Target
- One clock. There are four — first response, acknowledgement, resolution, closure — and each runs, pauses and breaches independently.
- Calendar
- What counts as time. A four-hour target on a business calendar means four working hours.
- Snapshot
- Each SLA freezes the policy it was created with, so editing a policy never rewrites what was already measured.
An SLA is attached automatically when an issue is created, and re-evaluated every time the issue is saved. Between saves, the background task watches the clock.
3.Business calendars
Administration → SLA → Business calendars. A calendar decides what counts as elapsed time.
| Field | What it does |
|---|---|
| Time zone | The zone the working hours are written in. 09:00 means 09:00 there. |
| 24×7 | One SLA hour equals sixty real minutes. Working hours and holidays are ignored entirely. |
| Working hours | Per weekday, as HH:MM. Leave a day empty and it does not count. |
| Default | Used when neither the policy nor the project names a calendar. |
Split shifts
Each day offers two periods. Fill both to express a lunch break — 09:00–13:00 and 14:00–18:00. Time between them does not count. Overlapping periods are merged.
To remove a day, clear both of its times and save. There is no separate delete control — an emptied period is the removal.
Time zones and daylight saving
Working hours are wall-clock. 09:00–18:00 stays 09:00–18:00 local across a daylight-saving change, so a working day legitimately contains eight, nine or ten real hours on a transition day. That matches how people actually work.
Policy → calendar → project → plugin default → Redmine default → UTC. The viewer’s time zone is deliberately not involved: an SLA duration must not change depending on who is looking at it. Only the display is localised.
4.Holidays
Per calendar, under Holidays.
| Field | What it does |
|---|---|
| Recurring | Only the day and month are matched, so the entry repeats every year. Use it for fixed-date holidays. |
| Special working day | Makes an otherwise non-working day count, using the hours you give it — a worked Saturday before a release. |
A fixed-date entry beats a recurring one for the same day, so you can override a single year of an annual holiday without deleting it.
A round-the-clock calendar ignores them by definition. If your holidays seem to be ignored, check which calendar the policy is actually using — a project can override it.
5.SLA policies
Administration → SLA → SLA policies.
Targets
Enter durations the way you say them: 30 (minutes), 4h, 1d, or 1d 4h. Leave a target empty and no clock is created for it — a policy with only a first response target is perfectly valid.
| Target | Measures from creation until… |
|---|---|
| First response | the first qualifying reply |
| Acknowledgement | the issue is picked up |
| Resolution | the issue is resolved |
| Closure | the issue is closed |
What starts and stops each clock
Nothing here is hard-coded. First response event decides what counts as a reply:
- First public comment — the first non-private note. The usual choice.
- First comment including private — internal notes count too.
- First reply from a project member — notes from outsiders do not stop the clock.
- First status change — a triage move counts as a response.
- Any first update — anything at all.
Ignore updates from the issue author is on by default, so a reporter chasing their own ticket does not satisfy your SLA.
Resolution and closure can fire when the issue reaches any closed status, one of a chosen set of statuses, or (resolution only) 100% done.
Reopening an issue does not un-resolve it. The first qualifying event stops that clock for good, which is what keeps historical measurements stable.
Warning and critical
Percentages of the target — 75% and 90% by default. They are materialised into real timestamps when the clock starts, so an alert fires before the deadline rather than being noticed after it.
6.Conditions
Conditions decide which issues a policy applies to. Each row reads as a sentence:
When the issue's Priority is one of High, UrgentWhen the issue's Tracker is one of Bug
Every condition must match. The example above applies only to high-priority bugs. A policy with no conditions matches every issue — that is how you build a catch-all.
Values are picked from real names; you never type record IDs. Use Add condition for more rows. Operators are is one of, is none of, is set and is not set — the last two take no value.
Fields available: project, tracker, priority, status, category, author, assignee, group, customer, and any issue custom field. A project condition also matches its subprojects unless you untick that.
When several policies match
The most specific one wins. “Specific” is your own ordered list, set in the plugin settings — by default customer, then project, then tracker, then priority, then group. A policy constraining the customer therefore beats one constraining only the priority. Ties break on position.
Switch the strategy to position if you would rather the first matching policy by position simply win, and ignore specificity.
A policy marked Default never competes. It is only used when nothing else matches.
7.Pause rules
A pause rule says: while an issue sits in this status, stop these clocks. Each target is configured separately, which is the whole point.
| Status | First response | Acknowledgement | Resolution | Closure |
|---|---|---|---|---|
| Waiting for customer | — | — | pause | pause |
That row is the setup almost everyone wants. Resolution genuinely cannot progress while you wait on the customer — but if you have not replied at all yet, that is still your clock, so first response keeps running. Tick First response only for a status where your team is not expected to reply yet, such as “Awaiting triage”.
When a clock resumes, its due date and both thresholds move forward by exactly the working time lost. A pause over a weekend on a business calendar therefore costs nothing — no working time elapsed.
Rules under Administration → SLA → Pause rules apply to every policy. A policy can override any status on its own form, and its rule replaces the global one entirely for that status.
8.Project settings
Project → Settings → SLA, once the SLA module is ticked under Modules. Needs the manage_sla permission.
- SLA enabled
- Turns tracking on or off for this project. Turning it off freezes existing SLAs where they are — nothing is deleted or completed.
- Inherit from parent
- A subproject with no settings of its own follows the nearest ancestor that has them.
- Business calendar
- Overrides the policy’s calendar for this project.
- Time zone
- Overrides the calendar’s zone.
- SLA policies
- Restricts which policies may be assigned here. Select none to allow all.
9.The issue panel
Every tracked issue gains an SLA panel below its details, with one row per target:
| Target | State | Progress | Detail |
|---|---|---|---|
| First response | Met | 60% | Completed in 18m of 30m |
| Resolution | At risk | 82% | 2h 35m remaining, due today 16:30 |
| Closure | Breached | 142% | Overdue by 6h 50m |
The gauge shows how much of the target is used. Past the deadline the ring stays full while the figure keeps counting — 142% — so a breach cannot be mistaken for “just on target”. Hovering gives the real figures (“6h 20m of 4h used”).
Remaining time is computed live, so it is right even if the background task has not run recently. The panel also links to the SLA timeline, a full history of that issue’s SLA events.
10.Issue list filters and columns
SLA data is available in Redmine’s ordinary issue list, so you can build and save your own views.
| Filters | Columns |
|---|---|
| SLA policy, SLA status, SLA health, SLA breached, SLA due date, SLA remaining time (hours), first response status, resolution status | SLA, SLA status, SLA health, SLA due date, SLA remaining time, SLA breached, first response, resolution |
Columns sort and group, and export to CSV with everything else. A saved query such as SLA health is At risk, sorted by SLA due date makes a serviceable work queue.
SLA health and SLA breached are stored values, refreshed each time the background task runs — so their accuracy follows your cron interval. SLA due date is exact at all times.
11.Dashboard
Project → SLA, or the global one at /sla/dashboard.
Opens on the last two months; use the period chips or the date fields to change that, and clear both dates for all time. Every figure links to the issues behind it.
The compliance headline never appears alone — it carries its numerator (“6 of 8 targets met”), the window it covers, and a row per target, because a single percentage hides which target is at fault.
Only settled targets — ones that have finished, met or missed. A still-running clock has done neither, and counting it either way would make the figure drift as work progresses.
12.Reports
- Compliance
- Met versus breached, overall and per target, with the window stated.
- Response time
- Median, average, minimum, maximum and a distribution of first response times.
- Resolution time
- The same for resolution.
- Breaches
- Every breach with issue, project, customer, policy, priority, assignee, breach type, due date, actual date and overrun.
Filters — period, policy, tracker, priority — travel with you when you switch report, so the four are comparable. Each exports to CSV.
The median is shown first on the duration reports, deliberately: one three-day outlier drags an average badly, and seeing both side by side tells you whether that is happening.
“4h” on a business calendar means four working hours, not four hours on the wall clock. Only a 24×7 policy makes the two the same.
13.Alerts and email
Configure under Administration → Plugins → Redmine SLA:
- Notify on — SLA started, warning, critical, breached, met, paused, resumed.
- Notify — assignee (a group assignee expands to its members), author, watchers, users whose role can manage SLA, all project members, or extra addresses.
Recipients who cannot see the issue are dropped. Mail goes through Redmine’s own mailer, so the From address, headers and each recipient’s language come from Redmine.
Editing the wording
Administration → SLA → Email templates. Each row overrides one notification, for one language. Events with no template keep the built-in wording, so you never have to define anything here.
Every recipient gets the template matching their own language: an exact match first, then your All languages template, then the built-in text. Variables are written {{issue.subject}} and listed on the form — click one to insert it. Preview renders the result against sample values without saving.
A variable that does not exist is rejected when you save the template, rather than rendering as an empty space in a customer’s inbox.
14.Keeping it running
SLAs are attached and re-evaluated whenever an issue is saved. But an issue nobody touches still needs watching — and that is what most installations forget.
| Without the scheduled task | State |
|---|---|
| Breach flag on an untouched issue | never set |
| Warning and critical alerts | never fire |
| Notification emails | never sent |
| Dashboard counts and health filters | stale |
| Remaining time on the issue panel | always exact |
# run as the user that owns your Redmine installation*/5 * * * * cd /path/to/redmine && RAILS_ENV=production \ bundle exec rails runner 'RedmineSla::BackgroundProcessor.run' >> log/sla.log 2>&1
The interval is your worst-case delay between a threshold being crossed and its alert. Five minutes suits most sites and costs almost nothing: the task looks only at clocks that need attention, and one that has settled is never examined again. It is safe to run repeatedly and concurrently.
Administration → SLA tells you. The setup checklist shows “Background processing — never run”, or “last run 3 days ago” if cron stopped, and a banner appears until it is healthy.
15.Permissions
| Permission | Scope | Allows |
|---|---|---|
view_sla | project | The issue panel, dashboard, SLA issue list and query filters |
view_sla_dashboard | project | The dashboard |
view_sla_reports | project | The reports |
manage_sla | project | Project SLA settings; recalculate one issue |
manage_sla_policies | global | Policies and pause rules |
manage_sla_calendars | global | Calendars and holidays |
manage_sla_notifications | global | Email templates |
The three global permissions let you delegate SLA administration without handing out full Redmine administrator rights. Administrators always have them.
16.Editing policies later
Editing a policy never changes what was already measured. Every SLA carries a frozen copy of the configuration it was created with, so last quarter’s compliance figure stays exactly as reported. Issues predating an edit show a note on their panel.
To apply an edited policy to existing records on purpose, use Administration → SLA → Recalculate. Choose Open SLAs only unless you really mean otherwise; targets that already completed or breached are never rewritten, and recalculation sends no notifications.
Ticking Rebuild the frozen policy snapshot discards the original configuration for those records. That is occasionally what you want — after fixing a wrong calendar — but it is not reversible.
17.Troubleshooting
| Symptom | Usual cause |
|---|---|
| New issues get no SLA | The SLA module is not ticked, or SLA is disabled in the project settings. Both are needed. |
| Still no SLA | No policy matches. Remember every condition must match. Create a catch-all with no conditions and Default ticked. |
| A policy is skipped | It has no target set, or it is inactive, or the project restricts which policies may be used. |
| A 4h SLA is due four days later | Correct on a business calendar — four working hours from Friday afternoon land on Monday. Use a 24×7 calendar for real hours. |
| Due dates look hours off | Check which time zone the SLA actually used; the policy, calendar and project can each override. |
| Holidays ignored | They belong to a different calendar than the policy uses, or the calendar is 24×7. |
| Breaches only noticed on save | The background task is not scheduled. See Keeping it running. |
| No notification mails | Check the event is ticked, the policy has notifications enabled, someone matches a recipient group, and Redmine’s own mail works. |
| Panel appears unstyled | Redmine 4 and 5 only: run rake redmine:plugins:assets. |