Open-source project
kimai/kimai avatar
kimai/kimai

Kimai: self-hosted time tracking with invoicing built in

Kimai is the #1 open-source time-tracking application. From freelancers to companies and organisations - everyone can manage timesheets, generate reports, create invoices and so much more... Web-based multi-user application, available as On-Premise or SaaS version: https://www.kimai.org

5,050 stars855 forksPHPAGPL-3.0

At a glance

What is it?
Kimai is an AGPL-3.0 PHP/Symfony time-tracking application for freelancers and teams, installed via Docker or Composer. Its strength is timesheet-to-invoice workflow; its cost is a real server, a subdomain, and a database you maintain.
Who is it for?
Adopt Kimai if you need timesheets that turn into invoices and you can run PHP 8.2+ with MariaDB 10.6+ or MySQL 8.4+ on its own subdomain. Skip it if you want a single-file local timer, or if you cannot own database backups and version upgrades.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Kimai solves, and who it is actually for

Most time trackers stop at a list of hours. Kimai continues into the part freelancers and small agencies get paid for: turning those hours into invoices, exports and reports. The README describes it as a "professional grade time-tracking application" that handles "use-cases of freelancers as well as companies with dozens or hundreds of users", and the feature list is written around that second half: invoicing, data exports, user/customer/project specific rates, money and time budgets, advanced reporting.

The multi-user framing matters more than it sounds. Rates are attached per user, customer and project, which is what you need when a senior contractor and a junior contractor bill the same client at different prices. Authentication can come from SAML, LDAP or the internal database, with TOTP two-factor available, so an existing company directory can be reused instead of a second password. The README also lists multi-timezone and multi-language support, with translations hosted on Weblate.

If you are one person tracking hours against a single rate and you never send an invoice, the extra machinery is overhead. Kimai is aimed at people who bill other people.

The Symfony and Doctrine core behind the timesheets

Kimai is a PHP application built on Symfony and Doctrine, with Twig templates and a frontend assembled through Symfony Webpack Encore. The repository layout reflects that: src/ for application code, config/ for Symfony configuration, migrations/ for Doctrine migrations, templates/ for Twig, translations/ for locale files, public/ as the document root, and var/ for generated runtime data. Assets are pulled in through package.json, which lists Tabler, Bootstrap, Chart.js, FullCalendar and gridstack among its dependencies.

That stack explains the deployment shape. There is no standalone binary and no embedded database. The application expects a webserver in front of it, a PHP process behind it, and a MariaDB or MySQL server next to it. Doctrine migrations mean schema changes ship as versioned migration files rather than a schema you edit by hand, which is why the repository carries UPGRADING.md alongside UPGRADING-1.md and UPGRADING-3.md: major version jumps have their own instructions.

The integration surface is the JSON API named in the README. Anything the web interface does with timesheets can be reached programmatically, which is how punch-in tools, scripts and editor plugins attach to it. The plugin store is the other extension point, with both paid and free plugins listed on the project site.

Installing Kimai with Docker and logging your first timesheet

The README points at several installation routes: a Caddy with Docker Compose setup documented for Hetzner and DigitalOcean, an SSH setup using Git and Composer, Docker images published as kimai/kimai2 on Docker Hub in FPM-only and Apache variants, a Synology guide for the Docker version, and developer setups. The Dockerfile in the repository confirms the image families: it names fpm, apache and dev as the build bases.

The practical prerequisite list is short and non-negotiable. PHP 8.2 minimum, with 8.3, 8.4 and 8.5 supported. MariaDB 10.6 or newer, or MySQL 8.4 or newer. A webserver and a subdomain, because a subdirectory install is explicitly not supported. The required PHP extensions are gd, intl, json, mbstring, pdo, tokenizer, xml, xsl and zip.

The commands below are the ones the Dockerfile documents for local testing by the maintainer, building an Apache image from the repository checkout and running it as a container. They assume you are in the repository root.

bash
docker build --no-cache -t kimai-apache --build-arg BASE=apache .
docker run -d --name kimai-apache-app kimai-apache

After that, the container is running but not yet useful. You still need a database reachable from it and a webserver hostname pointing at it, because the README states a subdomain is required. Configuration values live in the environment file, which the repository ships as .env.dist and which you copy and edit rather than modify in place.

Once the login page answers, the first real task is creating a customer, then a project under that customer, then a timesheet entry against the project. That order exists because rates attach at all three levels, so a timesheet without a customer and project has nowhere to inherit a rate from. The README also mentions two entry modes: multi-timer and punch-in punch-out, plus tagging and advanced search and filtering for finding entries later.

Where Kimai is the wrong tool

The subdomain requirement is the first hard constraint, and it is easy to miss. The README states plainly that a subdirectory is not supported. If your hosting only gives you example.com/kimai, this is not the application for you without a hostname change.

The second constraint is operational. Kimai is a stateful web application with a relational database, and the README's update section points at two separate documents: the updates page and UPGRADING.md for version-specific steps. That split is a signal. Upgrades are not a single command you can run blind; some releases require reading the guide first. If nobody on your side is willing to read release notes before deploying, a hosted timer will cost less in the long run than a self-hosted one you upgrade carelessly.

The third is scope. Kimai tracks and bills time. It is not a project management suite, not a helpdesk, and not an accounting system. The invoicing feature produces invoices from tracked time; it does not replace bookkeeping. Teams expecting a single tool to cover sprint planning and payroll will find themselves integrating rather than consolidating.

Finally, the README does not document rollback. If an upgrade goes wrong, the documented path forward is the update and upgrading guides, not a stated rollback procedure. That silence is worth planning around: your database backup is the rollback.

Kimai against a hosted tracker and against a plain timer

The closest comparison is a hosted SaaS time tracker. The difference is not features so much as who holds the data and who pays per seat. A hosted tracker gives you a URL and a login and handles upgrades; Kimai gives you the database, the backups and the upgrade calendar. Kimai's own README acknowledges both paths, pointing at the Cloud version for people who do not want to host it. So the real choice is between running the AGPL-3.0 application yourself and using the vendor's hosted offering, not between Kimai and an unrelated product.

The second comparison is a lightweight local timer or a spreadsheet. Those win on setup time and lose on everything downstream: no per-customer rate resolution, no invoicing, no API, no multi-user permissions. If your billing is one rate and one client, the spreadsheet is genuinely better because it has no server to patch.

The third is a general issue tracker that happens to record hours. Those tools treat time as an attribute of a ticket. Kimai treats the timesheet as the primary record and attaches customers, projects and rates to it. If your billing is derived from tickets rather than from hours, the data model works against you.

Licence, upgrades and the maintenance bill

Kimai is licensed AGPL-3.0, and package.json records the licence as AGPL. That is a strong copyleft licence, and the network clause matters here: if you modify Kimai and let users interact with it over a network, the AGPL's obligations extend to that modified version. Running an unmodified copy for your own team is the ordinary case. Building a modified Kimai into a product you host for customers is the case where you should read the licence text carefully and, if the stakes are high, talk to a lawyer. Nothing here is legal advice.

The paid plugin store sits alongside the open-source core. Plugins are a separate commercial arrangement from the application licence, so a plugin purchase is a line item that does not disappear when the core stays free.

Maintenance cost is the part the feature list does not show. The last push to the repository was on 2026-09-10, and releases arrive every couple of weeks per the README's roadmap section, which means the upgrade treadmill is continuous rather than occasional. Each upgrade means a database migration and a check of UPGRADING.md. Budget for that in hours per year, and budget for backups, because the README documents the update path but not a rollback.

Editorial conclusion

Adopt Kimai if you need timesheets that turn into invoices and you can run PHP 8.2+ with MariaDB 10.6+ or MySQL 8.4+ on its own subdomain. Skip it if you want a single-file local timer, or if you cannot own database backups and version upgrades. Before committing, verify three things on your own host: that your PHP build has gd, intl, json, mbstring, pdo, tokenizer, xml, xsl and zip; that you can serve it on a subdomain rather than a subdirectory; and that you have read UPGRADING.md for the version you are moving from, because that file, not the README, carries the version-specific steps.

Frequently asked questions

What is Kimai?

Kimai is an open-source, web-based time-tracking application built with PHP and Symfony. Its README lists invoicing, data exports, a JSON API, multi-timer and punch-in punch-out modes, and multi-user permissions among its features.

Is Kimai free?

The application is free and open-source under AGPL-3.0, and the README describes it as "free and open-source". Hosting is not free: you supply the server and database, and the project also offers a paid Cloud version and a plugin store with paid plugins.

Is Kimai open source?

Yes. The repository is licensed AGPL-3.0 and package.json records the licence as AGPL. The source, including migrations, templates and translations, is in the public repository.

How to install Kimai on Ubuntu?

The README does not give an Ubuntu-specific procedure. It lists documented routes including an SSH setup with Git and Composer, Docker images published as kimai/kimai2 in FPM and Apache variants, and Caddy with Docker Compose guides for Hetzner and DigitalOcean. Requirements are PHP 8.2 or newer, MariaDB 10.6+ or MySQL 8.4+, and a subdomain.

How to use Kimai?

The README points to the project documentation at kimai.org/documentation for usage. In practice you create a customer, then a project under it, then log time against the project, since rates can be defined per user, customer and project.

Official sources

  1. kimai/kimai on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kimai-kimai.svg)](https://hysenlabs.com/projects/kimai-kimai)