---
title: 10-minute quickstart | Tiger Data Docs
description: Get started with self-hosted TimescaleDB in about 10 minutes
---

This guide helps you run TimescaleDB locally, create your first hypertable with the columnstore enabled, write data to the columnstore, and see instant analytical query performance.

## Prerequisites for this procedure

To follow these steps, you'll need:

- Docker installed on your machine
- 8GB RAM recommended
- The `psql` client (included with PostgreSQL) or any PostgreSQL client like [pgAdmin](https://www.pgadmin.org/download/)

## Step 1: Start TimescaleDB

Start TimescaleDB using one of these options.

- [One-line install (recommended)](#tab-panel-584)
- [Manual Docker command](#tab-panel-585)

The easiest way to get started:

Important

This script is intended for local development and testing only. Do not use it for production deployments. For production-ready installation options, see the [TimescaleDB installation guide](/get-started/choose-your-path/install-timescaledb/index.md).

On Linux or Mac:

Terminal window

```
curl -sL https://tsdb.co/start-local | sh
```

This command:

- Downloads and starts TimescaleDB, if not already downloaded.
- Exposes PostgreSQL on port `6543`, a non-standard port that avoids conflicts with other PostgreSQL instances on port 5432.
- Automatically tunes settings for your environment using timescaledb-tune.
- Sets up a persistent data volume.

Run TimescaleDB directly with Docker. This option also works on Windows:

Terminal window

```
docker run -d --name timescaledb \
    -p 6543:5432 \
    -e POSTGRES_PASSWORD=password \
    timescale/timescaledb-ha:pg18
```

This example uses port `6543`, mapped to container port 5432, to avoid conflicts if you have other PostgreSQL instances running on the standard port 5432.

Wait about 1 to 2 minutes for TimescaleDB to download and initialize.

## Step 2: Connect to TimescaleDB

Connect using `psql`:

Terminal window

```
psql -h localhost -p 6543 -U postgres
# When prompted, enter password: password
```

You should see the PostgreSQL prompt. Verify TimescaleDB is installed:

```
SELECT extname, extversion FROM pg_extension WHERE extname = 'timescaledb';
```

Expected output:

```
   extname   | extversion
-------------+------------
 timescaledb | 2.x.x
```

Tips

Prefer a GUI? If you would rather use a graphical tool instead of the command line, you can download [pgAdmin](https://www.pgadmin.org/download/) and connect to TimescaleDB using the same connection details (host: `localhost`, port: `6543`, user: `postgres`, password: `password`).

## Step 3: Create your first hypertable

Create a hypertable for IoT sensor data with the columnstore enabled:

```
-- Create a hypertable with automatic columnstore
CREATE TABLE sensor_data (
    time TIMESTAMPTZ NOT NULL,
    sensor_id TEXT NOT NULL,
    temperature DOUBLE PRECISION,
    humidity DOUBLE PRECISION,
    pressure DOUBLE PRECISION
) WITH (
    tsdb.hypertable
);
```

`tsdb.hypertable` converts this into a TimescaleDB hypertable.

See more:

- [Create a hypertable](/learn/hypertables/creating-and-configuring-hypertables/index.md)
- [Set up hypercore](/build/columnar-storage/setup-hypercore/index.md)

## Step 4: Insert sample data

Add some sample sensor readings:

```
-- Enable timing to see time to execute queries
\timing on


-- Insert sample data for multiple sensors
-- SET timescaledb.enable_direct_compress_insert = on to insert data directly to the columnstore (columnnar format for performance)
SET timescaledb.enable_direct_compress_insert = on;
INSERT INTO sensor_data (time, sensor_id, temperature, humidity, pressure)
SELECT
    time,
    'sensor_' || ((random() * 9)::int + 1),
    20 + (random() * 15),
    40 + (random() * 30),
    1000 + (random() * 50)
FROM generate_series(
    NOW() - INTERVAL '90 days',
    NOW(),
    INTERVAL '1 seconds'
) AS time;


-- Once data is inserted into the columnstore we optimize the order and structure
-- this compacts and orders the data in the chunks for optimal query performance and compression
DO $$
DECLARE ch TEXT;
BEGIN
    FOR ch IN SELECT show_chunks('sensor_data') LOOP
        CALL convert_to_columnstore(ch, recompress := true);
    END LOOP;
END $$;
```

This generates \~7,776,001 readings across 10 sensors over the past 90 days.

Verify the data was inserted:

```
SELECT COUNT(*) FROM sensor_data;
```

## Step 5: Run your first analytical queries

Now run some analytical queries that showcase TimescaleDB's performance:

```
-- Enable query timing to see performance
\timing on


-- Query 1: Average readings per sensor over the last 7 days
SELECT
    sensor_id,
    COUNT(*) as readings,
    ROUND(AVG(temperature)::numeric, 2) as avg_temp,
    ROUND(AVG(humidity)::numeric, 2) as avg_humidity,
    ROUND(AVG(pressure)::numeric, 2) as avg_pressure
FROM sensor_data
WHERE time > NOW() - INTERVAL '7 days'
GROUP BY sensor_id
ORDER BY sensor_id;


-- Query 2: Hourly averages using time_bucket
-- Time buckets enable you to aggregate data in hypertables by time interval and calculate summary values.
SELECT
    time_bucket('1 hour', time) AS hour,
    sensor_id,
    ROUND(AVG(temperature)::numeric, 2) as avg_temp,
    ROUND(AVG(humidity)::numeric, 2) as avg_humidity
FROM sensor_data
WHERE time > NOW() - INTERVAL '24 hours'
GROUP BY hour, sensor_id
ORDER BY hour DESC, sensor_id
LIMIT 20;


-- Query 3: Daily statistics across all sensors
SELECT
    time_bucket('1 day', time) AS day,
    COUNT(*) as total_readings,
    ROUND(AVG(temperature)::numeric, 2) as avg_temp,
    ROUND(MIN(temperature)::numeric, 2) as min_temp,
    ROUND(MAX(temperature)::numeric, 2) as max_temp
FROM sensor_data
GROUP BY day
ORDER BY day DESC
LIMIT 10;


-- Query 4: Latest reading for each sensor
-- Highlights the value of Skipscan executing in under 100ms without skipscan it takes over 5sec
SELECT DISTINCT ON (sensor_id)
    sensor_id,
    time,
    ROUND(temperature::numeric, 2) as temperature,
    ROUND(humidity::numeric, 2) as humidity,
    ROUND(pressure::numeric, 2) as pressure
FROM sensor_data
ORDER BY sensor_id, time DESC;
```

Notice how fast these analytical queries run, even with aggregations across millions of rows. This is the power of TimescaleDB's columnstore.

## Next steps

Now that you have TimescaleDB running locally, explore more:

- [Create continuous aggregates](/build/continuous-aggregates/create-a-continuous-aggregate/index.md) for faster real-time analytics.
- [Connect your app](/get-started/quickstart/connect-your-app/index.md) to TimescaleDB.
- [Try a tutorial](/build/examples/simulate-iot-sensor-data/index.md) with a real-world dataset.
