Docs refreshed for Astervis v1 — now covering AI call analytics. What’s new
Astervis Docsv1.0
Configuration

Timezone Configuration

Get call times right across the stack.

A call that shows up three hours off isn't a small annoyance — it makes shift reports, missed-call windows, and after-hours QA rules wrong everywhere. The good news is that Astervis stores time correctly by design; almost every "wrong time" problem comes down to one or two settings not matching reality. This page walks through the three layers that decide what a timestamp looks like, how to find the right values, and how to apply them.

The default for a fresh install is Asia/Tashkent. The database itself always stores time in UTC — the settings below only change how that UTC value is read in from your PBX and displayed back to your users.

The three layers

Astervis handles a timestamp at three distinct points. Each has its own job, and getting time right means getting all three to agree.

Storage — always UTC

The TimescaleDB store keeps every call time in UTC. There's nothing to configure here, and you should never try to change it.

Input — MYSQL_TIMEZONE

Tells Astervis which timezone your PBX used when it wrote calldate, so the value can be normalised to UTC correctly.

Display — TIMEZONE / NEXT_PUBLIC_TIMEZONE

The timezone the backend and admin UI render timestamps in. This is what your team actually sees.

Storage: UTC, always

Your CDR analytics live in TimescaleDB (PostgreSQL 16) as UTC timestamps. This is deliberate: UTC has no daylight-saving jumps and no ambiguity, so historical data stays comparable forever. You don't set a variable for this layer — it's how the data is written, full stop.

Input: MYSQL_TIMEZONE

Asterisk and FreePBX write each call's calldate into MariaDB using the PBX server's local time, with no timezone marker attached. To turn that bare local time into UTC, Astervis needs to know which timezone the PBX was in. That's MYSQL_TIMEZONE.

This is the single most important setting on the page. If it's wrong, every call is shifted by the difference between the real PBX timezone and the one you told Astervis — and because the shift happens at write time, fixing it later doesn't retroactively repair rows that were already stored.

MYSQL_TIMEZONE must match the actual timezone your PBX server runs in, not the timezone your office is in or the timezone you'd like to display. Find it with the commands below before you guess.

Display: TIMEZONE and NEXT_PUBLIC_TIMEZONE

Once data is safely in UTC, the display layer converts it back into a human timezone on the way out. Two variables drive this:

  • TIMEZONE — used by the backend when it formats times (reports, exports, API responses).
  • NEXT_PUBLIC_TIMEZONE — used by the admin UI in the browser.

Astervis shows the same time to everyone based on these server-side settings — it does not follow each visitor's browser timezone. That's a feature: a supervisor in one city and an operator in another see identical numbers on the dashboard. Keep these two values equal to each other, and you'll usually want them equal to MYSQL_TIMEZONE as well, unless you deliberately want to display a different region.

How a timestamp travels

Here's the full journey of one call's time, from the moment it's written on the PBX to the moment it renders on a dashboard:

1. PBX writes the call
   Asterisk/FreePBX MariaDB cdr.calldate
   stored as bare LOCAL time, e.g. 2026-06-13 18:30:00  (no zone attached)

2. litcdc captures the change
   MariaDB binlog litcdc reads calldate

3. Normalise to UTC using MYSQL_TIMEZONE
   "18:30 in Asia/Tashkent" 13:30 UTC

4. Store in TimescaleDB
   cdr stored as 2026-06-13 13:30:00 UTC always UTC

5. Render for the user using TIMEZONE / NEXT_PUBLIC_TIMEZONE
   13:30 UTC "18:30"  shown on the dashboard

Read top to bottom, the rule is simple: MYSQL_TIMEZONE must describe step 1, and TIMEZONE / NEXT_PUBLIC_TIMEZONE decide step 5. When all three name the same region, what you see in step 5 equals what the PBX wrote in step 1 — exactly what you want.

Astervis replicates CDR through litcdc, a small Rust service that reads the MariaDB binlog and streams changes into TimescaleDB. It preserves calldate byte-for-byte; the timezone normalisation in step 3 is what turns that local value into UTC. See Sync & CDC for how the pipeline works.

Finding your PBX timezone

Before you set anything, confirm what timezone the PBX server actually uses. Run these on the PBX host (over SSH), not inside a container.

On most FreePBX / Sangoma / Ubuntu / Debian hosts:

timedatectl

Look at the Time zone: line, e.g. Time zone: Asia/Tashkent (+05, +0500). If timedatectl isn't available, fall back to:

cat /etc/timezone

Applying changes

All three settings live in /opt/astervis/.env. The file is owned by root and read by Docker Compose, so changes only take effect after you restart the stack.

Open the env file as root

sudo nano /opt/astervis/.env

Set all three to your PBX region

Use named timezones — never fixed UTC offsets (see the DST note below).

# How the PBX writes calldate — must match the PBX server's real timezone
MYSQL_TIMEZONE=Asia/Tashkent

# How times are displayed to your team (keep these two equal)
TIMEZONE=Asia/Tashkent
NEXT_PUBLIC_TIMEZONE=Asia/Tashkent

Restart the stack

cd /opt/astervis
docker compose down && docker compose up -d

Or use the installer's wrapper, which does the same thing:

sudo astervis-installer restart

A timezone change only affects how future times are normalised and how all times are displayed. Data already in the database is stored in UTC and isn't rewritten. Changing the display variables is always safe; changing MYSQL_TIMEZONE only matters for calls captured after the change — see the "wrong historical times" entry below for the case where past data was captured with the wrong value.

Common timezones

RegionTimezone
TashkentAsia/Tashkent
AlmatyAsia/Almaty
BishkekAsia/Bishkek
MoscowEurope/Moscow
KyivEurope/Kyiv
MinskEurope/Minsk
IstanbulEurope/Istanbul
LondonEurope/London
New YorkAmerica/New_York
Los AngelesAmerica/Los_Angeles

The full set of valid names is the IANA tz database. A handy reference is the list of tz database time zones.

DST and best practices

The one trap worth calling out explicitly is daylight saving time. Several of the regions Astervis serves don't observe DST (Uzbekistan, Kazakhstan, Russia), but others do (most of Europe and the Americas) — and the failure mode is subtle: times look correct for half the year and drift by exactly one hour after the clocks change.

Always use named timezones, never fixed offsets. A name like Europe/London carries the DST rules and switches automatically; a hard-coded +03:00 does not, so it silently goes an hour wrong on every DST transition.

# Wrong — frozen offset, breaks on DST changes
TIMEZONE=+05:00

# Right — named zone, handles DST automatically
TIMEZONE=Asia/Tashkent

A short checklist to keep time correct for good:

  • Match the PBX exactly. MYSQL_TIMEZONE is the keystone — verify it against timedatectl on the PBX, don't assume.
  • Keep the three settings consistent. Unless you have a specific reason to display a different region, set MYSQL_TIMEZONE, TIMEZONE, and NEXT_PUBLIC_TIMEZONE to the same value.
  • Use named zones only. This is what makes DST handle itself.
  • Settle it during setup. Get the timezone right at install time; changing MYSQL_TIMEZONE after data has accumulated won't fix the rows already captured.

Troubleshooting

Last updated on

On this page