Redmine time tracking and spent time reports

Redmine time tracking records hours against issues and projects so teams can bill clients and plan capacity. This page explains the configuration choices, setup sequence, reporting approach and limits to confirm before you build it.

On this page

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 choiceWhen it fitsTrade-off
Activities as a fixed list of work typesClient billing that maps each activity to a rate, or capacity reports that group hours by kind of workEvery extra activity adds a choice for users and more noise in reports, so keep the list short and stable
Time logged on issuesDelivery teams who need hours traced to specific tasks, and clients who ask which feature consumed timeUsers must pick an issue for each entry, which slows logging for work that has no ticket
Time logged on projects onlyOverhead, meetings or retainer work with no natural issue, and teams that report hours by project aloneReports cannot show effort per feature or ticket, and billing disputes are harder to resolve
Estimates kept as issue fieldsTeams that compare estimated and spent time per issue inside RedmineEstimates need upkeep as scope changes, and reports compare numbers that may be out of date
Estimates handled outside RedmineOrganizations where estimation lives in a finance, planning or contract tool that is the system of recordTwo sources must be reconciled, and Redmine reports will not show variance on their own
Required comments on time entriesClient invoices that need a short description of the work, or audits that ask what each entry coversUsers write filler text when comments are weak, and mandatory fields add friction to quick entries
Permission to log time for othersManagers or project leads who enter hours on behalf of staff, such as for absent or offline workEntries stop reflecting the person who did the work, so audit trails and capacity reports lose accuracy
Permission to edit or delete logged timePeriods that are closed for billing, where changes must be limited to a small groupRestrictive 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.