Redmine time tracking for billing and capacity: what it does and when you need it
Many teams already record their work in Redmine as issues, but cannot yet say how many hours went into each project, client or person. Redmine's time tracking module closes that gap. It lets users log time entries against an issue or directly against a project, and the spent time reports are built from those entries. Time tracking is part of Redmine's documented core feature set, next to issue tracking, roles and the Gantt chart, so the capability is standard rather than an add-on. What is not standard is the discipline around it: which activities exist, who may log time, and whether the entries are complete enough to bill from or plan capacity against.
The module earns its place when the hours have a consumer. Billing needs hours by client or contract, and often by activity, so that a fixed-price project and a time-and-materials project can be separated. Capacity planning needs hours by person and by period, so that a manager can compare logged effort with available days. Budget checks need hours compared with an agreed estimate per project or per version. If none of these outcomes are expected within the next few months, a lighter setup may be enough. If one of them is, the time data becomes a business record and deserves the same design attention as the issue workflow.
Before anything is configured, the reader should decide what a time entry means in their organization. The main design choices are the activity list (for example, development, testing, design, support or travel), whether time is logged only on issues or also on projects for work that has no ticket, and whether a client or contract is represented as a project, a parent project, or a custom field. Redmine's role permissions decide who can log time, edit it and view the reports, and these permissions should match who approves hours. The reader should also confirm how their current projects are structured, because reports are only as clean as the project hierarchy beneath them.
DeployOpen plans and configures time tracking in the client's own Redmine installation, with the activities, project structure, role permissions and report views agreed in writing before the build. The scope usually covers reviewing existing projects and trackers, agreeing the entry rules with the people who will use them, and testing that the reports produce the totals the finance or delivery team expects. Where the client needs hours in another system, the integration method and its limits should be confirmed separately, since it depends on the data they must export and how often.
Ask for the following in any proposal: a written list of activities and entry rules, the role matrix for logging and reporting, the reports to be delivered and who will check them, and an explicit statement of what happens to historical entries that do not meet the new rules. Confirm with your own team whether hours must be locked after invoicing, because that affects both permissions and the audit trail. Time tracking that is set up without these answers tends to produce reports that look complete but cannot be trusted in a billing dispute.
Which time tracking options fit which reporting need
This table compares the core Redmine settings that shape time data, including activities, issue-level versus project-level logging, estimates, comments and permissions. Read each row by starting with the reporting need you have, then check the option that fits it and the cost it adds to daily data entry. Confirm exact setting labels in the Redmine version you run, since menus differ between releases.
| Configuration choice | When it fits | Trade-off |
|---|---|---|
| Activities as a fixed list of work types | Client billing that maps each activity to a rate, or capacity reports that group hours by kind of work | Every extra activity adds a choice for users and more noise in reports, so keep the list short and stable |
| Time logged on issues | Delivery teams who need hours traced to specific tasks, and clients who ask which feature consumed time | Users must pick an issue for each entry, which slows logging for work that has no ticket |
| Time logged on projects only | Overhead, meetings or retainer work with no natural issue, and teams that report hours by project alone | Reports cannot show effort per feature or ticket, and billing disputes are harder to resolve |
| Estimates kept as issue fields | Teams that compare estimated and spent time per issue inside Redmine | Estimates need upkeep as scope changes, and reports compare numbers that may be out of date |
| Estimates handled outside Redmine | Organizations where estimation lives in a finance, planning or contract tool that is the system of record | Two sources must be reconciled, and Redmine reports will not show variance on their own |
| Required comments on time entries | Client invoices that need a short description of the work, or audits that ask what each entry covers | Users write filler text when comments are weak, and mandatory fields add friction to quick entries |
| Permission to log time for others | Managers or project leads who enter hours on behalf of staff, such as for absent or offline work | Entries stop reflecting the person who did the work, so audit trails and capacity reports lose accuracy |
| Permission to edit or delete logged time | Periods that are closed for billing, where changes must be limited to a small group | Restrictive rules push corrections into side channels, and broad rights weaken trust in reported hours |
How Redmine time entries flow into spent time reports
Every number in a Redmine spent time report starts as a single time entry. A user logs hours against an issue or directly against a project, and each entry carries a date, a number of hours, an activity such as Development or Review, and an optional comment. Redmine checks the user's role and project membership before accepting the entry, and the same roles decide who can see which entries and reports. The report itself does not store anything new. It reads existing entries and groups them by project, user, activity, version or custom field, so the report is only as clear as the data that was entered.
That is why the quality of the reports depends on decisions made before the first entry is logged. The activity list is shared across the instance and per project, so if teams create near-duplicate activities such as Dev, Development and Coding, totals split across them and no one can compare capacity between teams. Custom fields on time entries are the place to store client, contract or billing codes. If those codes are free text, spelling variations will fragment the totals, so the reader should decide early whether the field is a fixed list, who maintains it, and whether it is required. Confirm in your own installation which custom field types and target objects are available for time entries before you design the model around them.
Permissions shape both entry and visibility. A common pattern is to let users log and view their own time, let project managers see totals across the project, and reserve access to other people's entries for a small group, such as finance or a delivery lead. Redmine's role settings control whether members can view time entries, view spent time reports, edit or delete entries, and log time on issues. Test these with an account from each role before the reports are relied on, because a manager who can see totals but not the underlying entries will need a different report than one who can drill down. Note that role names and permission labels can change between releases, so verify them against the version you deploy.
Downstream billing and capacity tools usually read the data through the REST API rather than from the database. Redmine treats time entries as a core resource in its REST API, and that resource is marked stable, so an export job or billing connector can request entries by project, user or date range and receive them in JSON or XML. The API must be enabled by an administrator, and access uses either HTTP basic authentication or a per-user API key. Before you build on it, confirm the exact endpoints, filter parameters and response fields against the Redmine version you run, and test the export with a non-privileged API user so the integration cannot read more than the business needs.
Plan for change as the data grows. Activities that are renamed or deactivated can affect how historical totals read, and custom field values added later will not appear on older entries unless someone backfills them. Ask your implementation partner or internal owner to document the activity list, the custom field definitions, the role matrix and the API user model as one reference, and to decide who approves changes to any of them. Those four items determine whether the spent time reports remain comparable from one quarter to the next.
How to set up Redmine time tracking step by step
This sequence takes a Redmine instance from a version check to time entries whose totals match a manual count, with saved reports and a written procedure for users. Each step closes with a check you can record before moving on.
Confirm version and enable time tracking
An administrator starts on the Information page to record the installed Redmine version and database, since upgrade steps and report performance depend on both. Confirm the release is in the 7.0.x line, which the project lists as fully supported, or plan an upgrade first. Then project administrators switch on the Spent time module for each project in scope, and you decide whether subprojects inherit it. Check: the Spent time tab appears in the menu of each enabled project, a disabled project offers no time logging, and the version is written into your change record.
Define the activity list with leads
Finance and delivery leads agree the activity list people choose on each entry, such as design, development, testing, support or meetings. Name each activity so it maps to a billing line or a capacity category that the reports will group by. Administrators add these under time tracking enumerations, decide which are active, and set a default where one makes sense. Keep the list short enough that people choose without guessing. Check: both leads sign off the list in writing, and a test entry in each activity appears under the expected label in a grouped report.
Create custom fields for billing data
Add custom fields to time entries only where reports need them, such as client, contract or billing category. For each field, name an owner, define the allowed values for any controlled list, and decide whether the field is required. Confirm in your Redmine version that the field type can be set on time entries and used as a report filter, since support varies by field type. Check: create one test entry with every field populated, filter the spent time report by each field, and confirm the expected entries return.
Set roles for logging and viewing time
In the role permissions, grant logging, viewing and editing of spent time separately. Team members log their own time, project managers view project totals, and finance users see the full report across projects. Limit editing of other people's entries to a small group, and decide whether members may see time logged by colleagues on the same project. Check: sign in as one test user per role and confirm each can and cannot perform the expected actions on a sample entry, including editing an entry logged by someone else.
Configure required fields and estimates
Decide which information every entry must carry, such as a comment or a custom field value, and set the required timelog fields in the issue tracking settings so people cannot save an entry that billing depends on. Agree who maintains the estimated hours on issues and how often they are updated, so planned and logged effort can be compared. Confirm each option exists in your version before publishing guidance. Check: save an entry with a required field left blank and confirm it is rejected, then compare an issue's estimate with its logged total in a report.
Run test entries and reconcile totals
Ask two or three testers to enter time across at least two or three projects, using several activities and custom field values, and keep their own sheet of hours as the manual count. Generate the spent time report for the same date range and compare totals by project, user and activity against that sheet. Investigate every difference before go-live, checking filters, date ranges, subproject inclusion and the time zone of the server and users. Check: every total matches the manual count as entered, or each difference has a documented cause and a fix.
Build saved filters and the export route
Save report filters for the views finance and delivery leads use most, such as a monthly total by client or by billing category, and place them where those users will find them. Choose how figures leave Redmine: CSV export from the report, or the REST API, which exposes time entries as a stable resource but requires an administrator to enable the API and each user to hold an API key. Check: the exported file opens in your finance or reporting tool with the same totals as the on-screen report for the same filter.
Document the procedure for users
Write a short procedure covering how to log time from an issue, which activity and custom fields to choose, what the required fields are, how to correct an entry, and where to find saved reports. Name the owner who answers questions and the lead who approves changes to activities or fields. Publish the document where users already work, and link it from the project template so new projects inherit it. Check: a person who has not been involved logs and corrects an entry using only the document, and reports any step they could not complete.
Security and access considerations for time data
Time entries show more than hours. They can reveal who worked on which client engagement and when, and they sit in the same database that upgrades and backups depend on. The cards below cover who can see the data, how roles limit it, how export keys are scoped, and how backups protect it.
Who can see hours and rates
Time entries record the user who logged the hours, the project, the issue, the activity and the spent-on date. If your team stores rates in custom fields or through a plugin, that data sits alongside the entries. Before go-live, list every role that can open the time entry views and reports, then check whether any of those roles can see fields that hold rates. Test with a sample user from each role to confirm what appears.
Role limits per project
Redmine applies role-based access control through project memberships, so one person can hold different time permissions on each project. Review which roles may log time, edit other people's entries, and view reports across projects. Confirm that clients or contractors are assigned only to projects they should see. Recheck the role settings after any change, and log in as one user from each role to verify the result.
Scope API keys for exports
An administrator must enable the REST API before any export script can call it. Redmine accepts a per-user API key as a request parameter or in the X-Redmine-API-Key header, and the key carries the permissions of the account that owns it. Create a dedicated reporting account with only the project and time entry access the export needs. Do not reuse an administrator's key for scripts, and rotate the key when the script owner changes.
Access reviews in the routine
Time data can reveal staffing levels, who works on which client engagement and how much effort a project consumed. These patterns matter even when no single entry looks sensitive. Put access reviews into the operating routine on a fixed schedule. Compare current members and roles against the people who should still have them, remove former staff, and check the accounts used for API exports. Record each review so your security or audit team can see the outcome.
Back up the database
Time entries are stored in the Redmine database, so backups of that database are the copy of logged hours that matters most for recovery. Schedule backups often enough to match how frequently your team logs time, and store copies away from the server running Redmine. Supported databases include PostgreSQL, MySQL 8.0 to 8.4, SQL Server 2012 or higher, and SQLite, which the installation guide says is not suited to multi-user production use. Restore a backup into a test environment regularly to confirm it works.
Back up database and files first
The Redmine upgrade procedure calls for a backup of the database and the uploaded files before any change is made. Uploaded files live outside the database, so a database backup alone does not cover them. After the backup, the procedure copies configuration, uploads and third-party plugins to the new installation, then runs the database and plugin migrations before clearing the cache and restarting. Confirm the backup restores before you start the upgrade.
Building spent time reports for clients and projects
Most teams build spent time reports in Redmine by filtering the time entry report with the same fields they bill against. In practice that means choosing the project or subproject tree the client work sits under, a client or contract identifier held in a custom field on the project or on time entries, a date range that matches the billing period, and the activities that are billable. The time entry report can group and total results by those dimensions, and the output can be exported for invoicing. Before anyone relies on the report, confirm which filters, groupings and export formats your installed Redmine version provides, and test each one against a known set of entries rather than assuming a template exists. The main decision is where the billing logic lives. Keeping reports inside Redmine means the people logging time can see totals against the issues they worked on, and administrators can change the structure without a second system. Exporting results to a finance system or spreadsheet moves rate tables, tax handling, credit notes and invoice numbering out of Redmine, where they are usually easier to control and audit. Many organizations use a hybrid: Redmine produces a period-end extract of approved entries, and the finance system applies rates and produces invoices. Whichever path you choose, decide where reconciliation happens. Someone should compare the exported totals with the invoice lines each period, and record any entries that were corrected after invoicing. Report structure depends on your data model. Client attribution usually relies on a custom field, a project hierarchy or a contract code, and activities define what is billable. If you rename an activity, retire one, change a custom field's format or move projects between parents, historical filters may stop matching the entries they matched before. A report for last year may then show different totals when rerun. Plan these changes as controlled events: record the old and new values, decide whether existing entries are reclassified, and rerun a sample of past periods to confirm the totals still reconcile. Before go-live, run a reconciliation exercise with one closed billing period. Compare the Redmine export with invoices that were already issued, and document every difference, including rounding, entries logged to the wrong project and entries without a client attribute. Agree who owns the report definitions, who may change custom fields and activities, and how changes are approved. These controls matter more for billing than for capacity reporting, because a small change in filter logic can move hours between clients without anyone noticing until a customer disputes an invoice. If you are scoping this work with a partner, ask for the report definitions to be written down as a specification: the filters, groupings, export columns and the expected totals for a test period. Ask who will validate the output against invoices and how the team will handle changes to activities or custom fields after go-live. Those answers will show how much of the effort is configuration and how much is ongoing governance.
Limits to confirm in your environment before you rely on the reports
Spent time reports are only as reliable as the platform, data and rules behind them. The cards below list the points to confirm in the target installation before anyone bills a client or plans capacity from Redmine figures.
Redmine version and feature fit
Confirm which Redmine line you will run and whether its feature set covers your time tracking plan. Redmine 7.0.x is the fully supported line, 6.1.x and 6.0.x receive only fixes or important security updates, and 5.1.x and older are unsupported. Check the version against the time entry features, reporting options and plugins your billing process depends on before you build reports on it.
Database choice for production
The installation guide states that SQLite is not suited to multi-user production use, so a time tracking instance shared by billing and delivery staff needs a supported production database. Confirm which of PostgreSQL, MySQL 8.0 to 8.4 with READ COMMITTED isolation, or SQL Server 2012 or higher your organization will operate, and who backs it up. Reports drawn from a database that was not designed for concurrent writes can be unreliable.
Plugins for client billing and rates
Core Redmine records hours against issues, projects, users and activities, but it does not provide client-level invoicing or a rate card as a standard feature. Decide whether client rates, billable flags and invoice-ready totals are needed, then confirm which plugins provide them, whether each supports your Redmine version, and who maintains them through upgrades. Treat any plugin you have not tested as a dependency to verify, not a given.
Timezone and rounding rules
Hours logged across time zones and rounding to billing increments can change totals on client invoices. Confirm the server and user time zone settings, the date each entry is stored against, and whether your contracts round per entry, per day or per invoice line. Test a sample of entries logged near midnight and at the end of a billing period so the report matches the figures your finance team expects.
Entries from integrations
Hours can reach Redmine from the REST API, from commit messages through SCM integration, or from other tools connected to your environment. Decide which sources may create time entries, who owns each entry, and how corrections are made when an integration logs the wrong issue or duration. Confirm that the API is enabled by an administrator and that each integration user can only write the entries it is meant to write.
Historical hours from other tools
The built-in importers for Trac and Mantis are marked obsolete and not working, and third-party migration scripts for other systems are neither tested nor supported. Historical hours recorded elsewhere therefore need a separate plan, such as keeping the old system read-only for archive reporting or agreeing a documented manual import for the periods that matter to billing. Confirm this before promising clients continuous history in Redmine.
Questions buyers ask about Redmine time tracking setup and cost
Does Redmine time tracking require a software license?
No. Redmine is free software released under the GNU General Public License v2, and it has no paid edition. The cost of a Redmine time tracking setup comes from the infrastructure it runs on, the people who configure it, any plugins you adopt, the upgrades you schedule and the staff who maintain it. When you request a quote, ask the provider to separate one-time work (activity design, reports, data preparation) from recurring work (hosting, upgrades, plugin maintenance, administration). Also confirm which plugins are in scope, since each one adds licensing review, testing and upkeep of its own.
How long does Redmine time tracking setup take?
The duration depends mainly on the scope you define, so no fixed figure applies to every organization. The main drivers are the number of activities and how they map to billing or capacity rules, the reporting rules you need for clients and projects, any integrations such as commit-message logging or external billing systems, and whether historical time entries must be migrated. A small team with a short activity list and standard reports will finish far sooner than a firm with per-client rate tables and years of data. DeployOpen scopes time in writing before work starts, so ask for a written plan that lists each of these drivers.
What does our team need to provide for a time tracking project?
Three things matter most. First, decision makers who can sign off the activity list, billing codes, rounding rules and who may edit time after the fact, because these choices drive most of the rework when left open. Second, a test environment that mirrors your production configuration so reports can be checked before go-live. Third, a named administrator who can create custom fields, roles and projects, approve changes and answer questions during the build and after handover. Ask the provider to confirm these responsibilities in the written scope so that delays caused by missing decisions are visible early.
Can our own team set up Redmine time tracking without outside help?
Yes, for many organizations. A team with Redmine experience can usually configure a simple activity list, enable time logging on issues and build standard spent time reports from the built-in filters. Outside help tends to pay off when you need complex client billing with multiple rate tables, reports that reconcile to invoices, or migration of historical time data from another tool. Those areas involve data rules that are easy to get wrong and hard to correct later. A practical approach is to pilot the simple parts internally, then decide on the complex parts once you know the real volume and rules.
Which Redmine version should we use for time tracking?
Plan new work on Redmine 7.0, which is the fully supported line and receives new features, bug fixes and security updates. Redmine 6.1 receives only bug fixes and security updates, and 6.0 receives only important security updates. Redmine 5.1 and older are unsupported. Confirm the current stable release on the Redmine download page before you commit to a version, because release dates change. If you already run an older version, include the upgrade in the scope, since time entries, custom fields and plugins must carry over cleanly.
Does time tracking data in Redmine survive an upgrade?
It should, when the upgrade follows the documented procedure. The Redmine upgrade guide calls for backing up the database and uploaded files, copying configuration, uploads and third-party plugins to the new installation, running the database migrations and the plugin migrations, then clearing the cache and restarting. The risk lies mostly in plugins that add time tracking fields or reports, since they may not support the new version. Ask for a test upgrade on a copy of production data, and confirm that spent time totals match before and after.
Can Redmine time entries be imported from another tool such as Jira or Trac?
Not with the built-in tools alone. The built-in importers for Trac and Mantis are marked obsolete and not working, and the third-party migration scripts listed for systems such as Jira are described as neither tested nor supported. Historical time entries therefore usually need a custom mapping and validation step. Ask the provider to show how source users, projects, activities and dates map to Redmine, and how totals will be reconciled against the source system before the old data is retired.
How DeployOpen scopes and delivers Redmine time tracking
DeployOpen configures Redmine time tracking and spent time reports inside infrastructure you control, starting from how your teams bill, plan capacity and review work. The written scope fixes activities, logging paths, estimates and report definitions before any configuration begins, so the finished setup matches the way your organization reports time.
How we scope
- The written scope lists the activities, roles and projects that may log time in Redmine.
- It defines whether time is logged from issues, from commit messages, or both, and who may edit past entries.
- It names each spent time report, its filters, its audience and the client or project fields it relies on.
How we build
- We configure time tracking settings, activities and permissions in a staging instance before production changes.
- We test logging from issues and, where scoped, commit messages, against the Git or other SCM integration you run.
- We build estimate fields and report queries, then check totals against a sample of logged entries agreed with your finance team.
How we hand over
- We document activities, permissions, custom fields, report definitions and the steps for adding a new project or client.
- We walk administrators and project managers through logging, correcting entries and running the reports.
- We deliver the configuration record and test results so your team can reproduce the setup or audit it later.
How we support
- Ongoing support, upgrades and testing of the time tracking setup are available as a retainer.
- Redmine upgrades are planned around the supported 7.0 line, with plugins and report queries retested before cutover.
- Changes to activities, clients or reports go through the same scope and documentation process as the original build.

