TigerData logo
TigerData logo
  • Product

    Product

    Tiger Cloud

    Robust elastic cloud platform for startups and enterprises

    TimescaleDB Enterprise

    Self-managed TimescaleDB for on-prem, edge and private cloud

    Open source

    TimescaleDB

    Time-series, real-time analytics and events on Postgres

    Search

    Vector and keyword search on Postgres

  • Industry

    Data Centers

    Energy & Utilities

    Oil & Gas Operations

    Smart Manufacturing

    Crypto

  • Docs
  • Pricing
  • Developer Hub

    Changelog

    Benchmarks

    Blog

    Community

    Customer Stories

    Events

    Support

    Integrations

    Launch Hub

  • Company

    About

    TigerData logo

    Timescale

    Partners

    Security

    Careers

Contact usStart a free trial
Tiger Data

Products

  • TimescaleDB
  • Tiger Cloud
  • TimescaleDB Enterprise
  • Postgres Search Stack

Industry

  • Data Centers
  • Energy & Utilities
  • Oil & Gas Operations
  • Smart Manufacturing
  • Crypto

Support

  • Cloud Status
  • Support
  • Security
  • Terms of Service
  • Code Of Conduct

Learn

  • Documentation
  • Blog
  • Tutorials
  • Changelog
  • Success Stories

Company

  • About
  • Contact Us
  • Careers
  • Newsroom
  • Brand
  • Events

Products

  • TimescaleDB
  • Tiger Cloud
  • TimescaleDB Enterprise
  • Postgres Search Stack

Industry

  • Data Centers
  • Energy & Utilities
  • Oil & Gas Operations
  • Smart Manufacturing
  • Crypto

Support

  • Cloud Status
  • Support
  • Security
  • Terms of Service
  • Code Of Conduct

Learn

  • Documentation
  • Blog
  • Tutorials
  • Changelog
  • Success Stories

Company

  • About
  • Contact Us
  • Careers
  • Newsroom
  • Brand
  • Events
Privacy preferencesLegalPrivacySitemap

Subscribe to the Tiger Data newsletter

Gold Partner with Inductive Automation — Ignition

2026 (c) Timescale, Inc., d/b/a Tiger Data.
All rights reserved.

Tiger Data
GOLD PARTNER WITHINDUCTIVE AUTOMATION

2026 (c) Timescale, Inc., d/b/a Tiger Data.
All rights reserved.

Privacy preferencesLegalPrivacySitemap

How to Simulate a Basic IoT Sensor Dataset on PostgreSQL

Ajay Kulkarni

By Ajay Kulkarni

December 28th, 2023

4 min

Share

Ajay Kulkarni

By Ajay Kulkarni

December 28th, 2023

4 min

Share

Copy as HTML

Open in ChatGPT

Open in Claude

Open in v0

Tutorials

IoT

Table of contents

  1. 01 Simulating IoT Data in PostgreSQL: Prerequisites
  2. 02 Setting Up Your Tables
  3. 03 Creating the Simulated IoT Sensor Data
  4. 04 Next Steps
Get started for free
A smart home with various IoT devices. Learn how to query simulated IoT sensor data using TimescaleDB

The Internet of Things (IoT) describes a trend in which computing is becoming ubiquitous and embedded in more physical things. For many of these things, the purpose of IoT is to collect sensor data about the environment in which it exists, e.g., oil wells, factories, power plants, farms, moving vehicles, office buildings, and homes.

In other words, IoT is all about data. The datasets generated by IoT devices are generally time series in nature, with relational metadata to describe those things. Simulating IoT sensor data, for example, when testing a new system, is often necessary. 

This tutorial shows how to simulate a basic IoT sensor dataset on PostgreSQL or TimescaleDB, which supercharges vanilla PostgreSQL with automatic data partitioning, always up-to-date materialized views, and a hybrid row-columnar storage engine.

✨
Unsure about whether to use PostgreSQL for IoT data? Here are eight reasons to do it.



For creating a more advanced simulated IoT dataset, try the Time-Series Benchmarking Suite.

Simulating IoT Data in PostgreSQL: Prerequisites

To complete this tutorial, you need a cursory knowledge of the Structured Query Language (SQL). The tutorial walks you through each SQL command, but it is helpful if you've seen SQL before. 

To start, install TimescaleDB. When your installation is complete, you can ingest or create sample data such as the data from the NYC Taxi Cab tutorial, and finish the steps in this guide.

Setting Up Your Tables

First, connect to your database via psql.

Second, create the sensors and sensor_data tables:

CREATE TABLE sensors( id SERIAL PRIMARY KEY, type VARCHAR(50), location VARCHAR(50) );
CREATE TABLE sensor_data ( time TIMESTAMPTZ NOT NULL, sensor_id INTEGER, temperature DOUBLE PRECISION, cpu DOUBLE PRECISION, FOREIGN KEY (sensor_id) REFERENCES sensors (id) );

If you are using TimescaleDB, convert the sensor_data table into a hypertable:

SELECT create_hypertable('sensor_data', 'time');

Next, populate the sensors table with four sensors:

INSERT INTO sensors (type, location) VALUES ('a','floor'), ('a', 'ceiling'), ('b','floor'), ('b', 'ceiling');

Finally, verify that the sensors were created correctly:

SELECT * FROM sensors;

After running that last SQL statement, you should see something like this:

id | type | location ----+------+---------- 1 | a | floor 2 | a | ceiling 3 | b | floor 4 | b | ceiling (4 rows)

Creating the Simulated IoT Sensor Data

This section shows the query results as examples, but because the tutorial generates random data every time it is run, your results will look different but share the same structure.

Generate a dataset for all of our four sensors and insert it into the sensor_data table:

INSERT INTO sensor_data (time, sensor_id, cpu, temperature) SELECT time, sensor_id, random() AS cpu, random()*100 AS temperature FROM generate_series(now() - interval '24 hour', now(), interval '5 minute') AS g1(time), generate_series(1,4,1) AS g2(sensor_id);

Verify that the simulated sensor data was written correctly:

SELECT * FROM sensor_data ORDER BY time;

Example output:

time | sensor_id | temperature | cpu -------------------------------+-----------+---------------------+----------------------- 2024-03-02 21:58:52.415591+00 | 2 | 34.74860895110643 | 0.7382245703719759 2024-03-02 21:58:52.415591+00 | 1 | 78.28644854140863 | 0.0538759700059126 2024-03-02 21:58:52.415591+00 | 4 | 84.34109828273877 | 0.2814163809100949 2024-03-02 21:58:52.415591+00 | 3 | 18.30145613996288 | 0.11061603685747601 2024-03-02 22:03:52.415591+00 | 1 | 28.8350892206531 | 0.5167745613330366 2024-03-02 22:03:52.415591+00 | 2 | 70.38494920417571 | 0.04132443651006601 2024-03-02 22:03:52.415591+00 | 4 | 91.39978680296652 | 0.5797557914264548 2024-03-02 22:03:52.415591+00 | 3 | 89.40911758654491 | 0.6911678473371399 ...

You've successfully created a basic IoT sensor dataset! Now let's run some queries.

Running basic queries

This section requires the installation of TimescaleDB.

Average temperature, average CPU by 30-minute windows:

SELECT time_bucket('30 minutes', time) AS period, AVG(temperature) AS avg_temp, AVG(cpu) AS avg_cpu FROM sensor_data GROUP BY period;

Sample output:

period | avg_temp | avg_cpu ------------------------+--------------------+--------------------- 2024-03-03 17:30:00+00 | 43.10768090240475 | 0.44125966982283243 2024-03-03 09:00:00+00 | 46.47069943057713 | 0.44783394066455323 2024-03-03 12:30:00+00 | 50.245161953350795 | 0.4173858962698807 2024-03-03 02:30:00+00 | 41.02991149971461 | 0.5369651925149536 2024-03-03 05:00:00+00 | 45.576655689044905 | 0.5800885979769893 ...

Average and last temperature, average CPU by 30-minute windows:

What if you don't just want the average temperature for each period but also the last temperature? For example, if you wanted to understand the final temperature value at the end of the interval:

SELECT time_bucket('30 minutes', time) AS period, AVG(temperature) AS avg_temp, last(temperature, time) AS last_temp, AVG(cpu) AS avg_cpu FROM sensor_data GROUP BY period;

Example output:

period | avg_temp | last_temp | avg_cpu ------------------------+--------------------+--------------------+--------------------- 2024-03-03 17:30:00+00 | 43.10768090240475 | 37.897223743142305 | 0.44125966982283243 2024-03-03 09:00:00+00 | 46.47069943057713 | 10.360343839058483 | 0.44783394066455323 2024-03-03 12:30:00+00 | 50.245161953350795 | 13.395952389199483 | 0.4173858962698807 2024-03-03 02:30:00+00 | 41.02991149971461 | 20.85346474997114 | 0.5369651925149536 2024-03-03 05:00:00+00 | 45.576655689044905 | 17.53287790099687 | 0.5800885979769893 ...

Using the sensor metadata

Now let's take advantage of some of the metadata you have stored in the sensors table:

SELECT sensors.location, time_bucket('30 minutes', time) AS period, AVG(temperature) AS avg_temp, last(temperature, time) AS last_temp, AVG(cpu) AS avg_cpu FROM sensor_data JOIN sensors on sensor_data.sensor_id = sensors.id GROUP BY period, sensors.location;

Example output:

location | period | avg_temp | last_temp | avg_cpu ----------+------------------------+--------------------+---------------------+--------------------- floor | 2024-03-03 17:00:00+00 | 57.7554057402912 | 70.92230873447865 | 0.5664165557316464 floor | 2024-03-03 13:00:00+00 | 49.10969984873296 | 95.18393076186942 | 0.2998594519486328 ceiling | 2024-03-03 01:30:00+00 | 43.23389752853527 | 84.23455916498523 | 0.415458435988545 ceiling | 2024-03-02 23:30:00+00 | 49.04287048373988 | 29.13487894000726 | 0.5481122939027164 floor | 2024-03-03 14:00:00+00 | 42.197390088314954 | 48.37367352541595 | 0.4302213965771769 ceiling | 2024-03-03 09:00:00+00 | 33.96200524565035 | 50.90505195144848 | 0.5037301372624226 floor | 2024-03-03 11:00:00+00 | 67.50318185485571 | 74.71978857954535 | 0.4930108855000481 ceiling | 2024-03-03 10:00:00+00 | 43.6388721380759 | 18.17060920674267 | 0.44136773995668604 ...

Next Steps

Congratulations, you now have a basic IoT sensor dataset you can use for testing in PostgreSQL or TimescaleDB. To learn more about the TimescaleDB concepts and functions you just used, please visit these pages in our developer documentation:

  • Hypertables
  • time_bucket
  • last

To see how other companies are using TimescaleDB in the IoT space, check out these stories:

  • From Ingest to Insights in Milliseconds: Everactive's Tech Transformation With Timescale
  • Visualizing IoT Data at Scale With Hopara and TimescaleDB

If you want to try TimescaleDB today, run it on your machine or simply create a free account.


About the author

Ajay Kulkarni

By Ajay Kulkarni

// Related posts

Yes, You Can Do Hybrid Search in Postgres (And You Probably Should)
Yes, You Can Do Hybrid Search in Postgres (And You Probably Should)

pg_textsearch

Cloud

Yes, You Can Do Hybrid Search in Postgres (And You Probably Should)

Most search stacks run four systems to answer one question. You don't need any of them. Build production hybrid search in Postgres with pg_textsearch for BM25, pgvectorscale for vector similarity, and Reciprocal Rank Fusion to combine them. One query. One database.

By Erin Mikail Staples

April 20th, 2026

How to Automate Data Classification in PostgreSQL With OpenAI
How to Automate Data Classification in PostgreSQL With OpenAI

AI

#Callout-pgaivector

How to Automate Data Classification in PostgreSQL With OpenAI

Data classification is a crucial but challenging task. Learn how to automate it in PostgreSQL using open-source extensions (pgvector; pgai) and OpenAI models.

By Team Tiger Data

November 22nd, 2024

Combining Semantic Search and Full-Text Search in PostgreSQL (With Cohere, Pgvector, and Pgai)
Combining Semantic Search and Full-Text Search in PostgreSQL (With Cohere, Pgvector, and Pgai)

AI

#Callout-pgaivector

Combining Semantic Search and Full-Text Search in PostgreSQL (With Cohere, Pgvector, and Pgai)

Read how you can implement hybrid search in PostgreSQL by combining semantic and full-text search using Cohere, pgvector, and pgai.

By Team Tiger Data

November 15th, 2024

Stay updated with new
posts and releases.

Receive the latest technical articles and release notes in your inbox.