AI Summary
This video demonstrates how to handle massive time-series data, using a network of EV charging stations that generates 630 billion rows per year as an extreme example. The presenter compares storing this data in a standard PostgreSQL database, splitting it across specialized databases, and using TimescaleDB, a PostgreSQL extension, to achieve significant performance and storage improvements. A live simulation with 500 virtual charging stations shows how TimescaleDB's hypertables, compression, and continuous aggregations enable fast queries and efficient storage.
Chapters
PostgreSQL handles time-stamped data well until tables reach hundreds of millions of rows, then performance degrades. The example used is an EV charging network generating over 630 billion rows per year.
Charging stations use the OCPP protocol and send four types of data: meter readings (voltage, current, power, energy), charging sessions (billing data), status updates (available, faulty), and configuration data (model, firmware).
A network of 10,000 charging devices sending readings every 30 seconds generates about 20,000 rows per second, totaling roughly 630 billion rows per year. The challenge is that meter readings and billing data are different types but must coexist for dispute resolution.
A single large table works initially but becomes dangerous as it grows to hundreds of millions of rows. Inserts slow down, and dashboard queries become full table scans, leading to failure within weeks, not years.
Many teams split data: time-series data into a specialized database like InfluxDB, and billing data into Postgres. This fails when a query needs to join data across both databases, requiring complex code to merge results and match timestamps.
Using a document database like MongoDB lacks real compression and time-range skipping, leading to endlessly growing storage costs. This problem is not unique to EV charging; it applies to IoT sensors, server logs, financial data, and user analytics.
TimescaleDB is an open-source extension for PostgreSQL, not a new database. It uses the same SQL, disk, and tools, and can be activated with a single line of code. Real companies have compressed 15 TB to 1 TB and reduced database costs from $9,000/month to $4.
The presenter runs a free service on Tiger Cloud and a simulator that mimics a real charging network with 500 virtual charging devices and 875 sockets. The simulation models each second of real time as 30 seconds of simulated time.
The schema includes a meter readings table (a hypertable), a billing sessions table (a regular PostgreSQL table), and a status events table (a hypertable). The hypertable is created with a single line: 'create hypertable'.
This table stores one row per charging session with who charged, when, how much energy, and the bill amount. It is intentionally a standard PostgreSQL table with primary and foreign keys, as billing data is not high-volume.
The database continuously fills with 1,100 to 1,200 rows per second. The presenter can query random customer bills and see full details, including connection time, duration, and charges.
The presenter creates a regular PostgreSQL database without TimescaleDB and runs the same queries. Initially, the regular database is 2.85 GB, while TimescaleDB is 3.47 GB because compression hasn't been applied yet.
TimescaleDB has built-in compression for time-series data. After manual compression, the size drops from 3.46 GB to 1.23 GB, about 30% of the original. With further compression, it goes below 1 GB.
A query calculating average power per charging device took almost 17 seconds in regular PostgreSQL, 5.4 seconds in TimescaleDB, and 1.7 seconds with continuous aggregations enabled—a 10x speedup.
TimescaleDB stores a small summary table with hourly data per device and automatically updates it as new data arrives. Dashboards never need to scan all 24 million rows, keeping queries fast even as data grows to billions.
For a billing dispute, a single SQL query joins the session table and the meter readings table (24 million rows). It returns 56 readings over 28 minutes, allowing verification of the bill against actual consumption.
The demo runs on the smallest Tiger Cloud instance with 2 GB RAM. Users can set up automatic tiering of old data to S3 storage, and Tiger has an MCP connector for AI tools like Claude or Cursor to manage the database.
For time-series data, enabling TimescaleDB is an obvious choice—it requires no changes to existing code and provides significant performance and storage benefits.
Mentioned in this Video
Tutorial Checklist
💡 Key Takeaways
Scale of the Problem
Quantifies the challenge: 20,000 rows per second and 630 billion rows per year, making the case for specialized solutions.
01:56TimescaleDB as a PostgreSQL Extension
Emphasizes that TimescaleDB is not a new database but an extension, requiring no code changes and using familiar SQL.
04:06Compression Impact
Shows a concrete storage reduction from 3.46 GB to 1.23 GB, demonstrating the practical benefit of compression.
10:04Continuous Aggregations
Explains how summary tables keep queries fast even with billions of rows, a key technique for time-series dashboards.
12:32Single Query for Billing Disputes
Illustrates the advantage of keeping all data in one database, enabling a simple SQL join for complex business logic.
13:25Full Transcript
[00:01] рано или поздно сталкивается каждый разработчик. Ваше приложение собирает данные с временными метками, и PostgreSQL прекрасно с ними справляется, пока таблица не достигает нескольких сотен миллионов строк, после чего всё рушится. В этом видео я покажу вам, как масштабные реальные системы
[00:15] решают именно эту проблему, используя самый экстремальный пример, который мне удалось найти, — сеть зарядных станций для электромобилей. Сейчас это генерирует более 630 миллиардов строк данных в год, и я даже создал собственную сеть зарядных станций с сотнями
[00:28] виртуальных зарядных устройств, чтобы показать вам, как это работает и как вы можете использовать эти ускорения работы вашей базы данных. Хорошо. Таким образом, в США количество из этих станций, по сути, представляет собой компьютер с сетевым подключением, который
[00:45] Теперь все эти зарядные устройства используют протокол OCPP. . А если посмотреть, что именно передается по этому соединению, то окажется, что там четыре типа данных. Итак, сначала вам нужно определить показания счетчиков. Итак, подумайте о
[00:59] напряжении, токе, мощности, энергии. Теперь каждое зарядное устройство круглосуточно отправляет показания примерно через 15-30 секунд после подключения к каждой розетке . Это довольно тяжелое изделие. Этот отправляет данные. Во-вторых, у нас есть сеансы зарядки. Вот тогда-то
[01:14] автомобиль к розетке. То есть, когда автомобиль подключается к зарядке, начинается новая сессия. Теперь, когда вы показания счетчика за эту сессию будут определять, сколько вам будет выставлено за пользование. Таким образом, это, по сути, данные для выставления счетов. А это ведь тоже деньги, верно? Потому что
[01:28] сумму. Таким образом, вы не можете потерять эту информацию или допустить ошибку. И наконец, в-третьих, обновления статуса. Итак, товар доступен, зарядка неисправна. Вот так парковке вышло из строя,
[01:41] скучные данные конфигурации. Итак, модель, прошивка, сколько существует розеток? Вы поняли идею. А теперь представьте, как масштабировать все это. Сеть из 10 000 зарядных устройств, отправляющая показания каждые 30 секунд, генерирует около 20 000 строк
[01:56] данных в секунду, понятно? Таким образом, это примерно 630 миллиардов строк в год. И настоящая сложность заключается в том, что показания приборов и данные для выставления счетов — это совершенно разные типы данных, но они должны сосуществовать.
[02:09] Потому что в тот момент, когда клиент оспаривает счет, вам необходимо объединить оба запроса в одном . Итак, возникает вопрос: как же на самом деле хранить 630 миллиардов строк данных? Первый вариант — использовать обычный PostgreSQL. Итак, у вас есть одна большая таблица,
[02:22] временной метке. И поначалу это отлично работает , что, собственно, и делает это опасным. Потому что по мере того, как таблица разрастается до сотен миллионов строк, в памяти, вставка данных начнет замедляться, и каждый запрос к панели мониторинга
[02:36] превратится в сканирование всей таблицы, которая буквально занимает место на жестком диске. Таким образом, в таких масштабах это произойдет не через годы, а через несколько недель. Второй вариант — это то, что
[02:48] обычно выбирает большинство команд. Поэтому они разделили данные. Они помещают показания в специализированную базу данных временных рядов, возможно, что-то вроде InfluxDB, а данные о выставлении счетов хранят в Postgres. Звучит вполне разумно. У вас есть два инструмента,
[03:00] . Но вот запрос, который окончательно разрушает эту схему. Например, кто-то оспаривает платеж в размере 40 долларов. Для разрешения этого спора вам потребуется их платежная документация, а также фактические показания счетчика электроэнергии за этот
[03:14] сеанс зарядки. Это объединение двух разных таблиц. Но данные о выставленных счетах PostgreSQL, а показания счетчика — в другой базе данных. И вы не сможете эффективно объединить данные из двух разных баз данных. Таким образом, теперь вы фактически
[03:26] запрашивать данные с обеих сторон, сопоставлять их, пытаться сопоставить временные метки и надеяться, что все совпадет. И вам приходится поддерживать этот код вечно, что довольно раздражает. Теперь третий вариант — поместить всё это в такую библиотеку, как MongoDB.
[03:40] отсутствует реальное сжатие и нет возможности пропускать данные по временному диапазону. А это значит, что ваши расходы на хранение будут расти бесконечно. И кстати, это ведь не просто проблема зарядных устройств для электромобилей, верно? Датчики IoT,
[03:54] журналы серверов, финансовые данные, аналитика пользователей, верно? Любой объект с постоянно увеличивающейся временной меткой в конечном итоге столкнется с этим же препятствием. Данное видео спонсируется компанией Tiger Data. И это потому, что они создали Timescale
[04:06] DB, стандартное решение с открытым исходным кодом для решения именно этой проблемы. что Timescale DB — это не новая база данных, просто расширение для PostgreSQL, поэтому вы используете тот же SQL-код, тот же диск, те же инструменты,
[04:21] активируете его буквально одной строкой кода. Таким образом, это меняет способ хранения данных, особенно для временных рядов, подобных этим. И реальные компании используют именно такой рабочий процесс с Timescale DB. Например,
[04:35] одна энергетическая компания сжала 15 терабайт данных до одного и сократила свои расходы на базу данных с 9000 долларов в месяц до всего лишь четырех. Теперь еще один пользователь заменил им четыре отдельные базы данных и получил примерно в 350 раз более быстрые запросы.
[04:49] вам покажу в этой демонстрации, работает на платформе Tiger Cloud, которая является бесплатная пробная версия, кредитная карта не требуется, и вы можете запустить базу данных примерно за описании на случай, если вы захотите посмотреть, но, конечно, давайте перейдем
[05:03] к демонстрации, и я хочу показать вам, как это работает на самом деле, чтобы вы могли увидеть, как обрабатывать такие огромные объемы данных. Итак, сейчас я я запустил бесплатный сервис на платформе Tiger Cloud и написал симулятор, который
[05:17] функционирует как настоящая сеть зарядных станций. Сейчас доступно 500 виртуальных зарядных устройств и 875 розеток. городам. У нас есть как быстрые , так и медленные зарядные устройства, и виртуальные автомобили могут подключаться, отключаться, начинать и останавливать сеанс зарядки, в общем,
[05:31] вы поняли идею. Здесь я моделирую каждую секунду реального времени, или, другими словами, 30 секунд смоделированного времени, и вы увидите, что у нас есть, например, электропитание сети, и здесь доступны все различные зарядные устройства. Я
[05:44] происходит, есть ли зарядное устройство, если оно неисправно, я могу нажать на кнопку, и мы сможем увидеть, что произошло, и получим все журналы и данные. Сейчас одновременно, и если я перейду сюда, мы увидим, что
[06:01] размер постоянно растет во время работы симуляции. Опять же, это призвано дать вам представление о том, что произойдет, если у нас будет даже 10 000 зарядных устройств, то есть в эту базу данных будет поступать гораздо больше данных. Итак,
[06:14] показать вам, как выглядит эта симуляция и как мы можем обрабатывать такой объем схему базы данных и различные таблицы, которые я здесь создал. Есть три основных момента, которые я хотел бы рассмотреть. Первая таблица содержит показания счетчиков, и именно она
[06:28] буквально завалена данными, потому что каждое показание с каждого зарядного устройства попадает в эту таблицу. Таким образом, буквально каждую секунду и бесконечно много строк появляются сотни строк. И здесь вы можете заметить, что это
[06:40] обычная таблица PostgreSQL. Единственное, что в нём особенного, добавил снизу. Итак, вот эта строка: create hypertable. Эта строка указывает TimescaleDB автоматически разделить эту таблицу на
[06:54] более мелкие части в фоновом режиме. В частности, он изготавливает один экземпляр в день. причина, по которой это важно, довольно проста.
[07:07] фрагмент данных за вчерашний день, вместо того чтобы перебирать всю таблицу целиком. Теперь вам не просто пишете эту одну строку, которую я вам здесь показал, и это произойдет автоматически специально для данных временного ряда.
[07:19] Теперь рассмотрим вторую таблицу, содержащую данные о сеансах тарификации, и именно она включает в себя всю информацию о выставлении счетов. Таким образом, для каждой сессии зарядки указывается одна строка: кто заряжал, когда сколько энергии использовал, и за какую сумму будет выставлен счет
[07:32] . И посмотрите, это совершенно стандартная обычная таблица PostgreSQL. В нем есть первичный ключ, у нас есть ссылки на внешние ключи , ничего особенного, верно? И это сделано намеренно, потому что данные о выставлении счетов — это не огромный объем информации, который поступает непрерывно
[07:44] . Это обычные реляционные данные, и мы можем держать их под контролем. фрагмента данных могут храниться в одной и той же базе данных, и в этой схеме я могу А третья таблица — это таблица событий состояния. По сути, это и есть
[07:59] состояние зарядного устройства меняется — доступно, неисправно, заряжается и т.д. — здесь будет появляться новая запись. Теперь у нас также есть гипертаблица, поскольку она может содержать больше здесь много информации. То же самое , это всего одна строка, что
[08:13] значительно ускоряет выполнение запроса. Здесь есть еще несколько запросов и таблиц, три основные таблицы, о которых нам нужно знать. Итак, если я вернусь к симуляции, я увижу, что она всё ещё работает. Мы все еще собираем данные, и
[08:25] это будет выглядеть на самом деле. Машины въезжают, машины выезжают, сессия информацию, снимаем показания датчиков, и все это одновременно добавляется в нашу базу данных. На данный момент база данных
[08:39] непрерывно заполняется и добавляется по 1100 или 1200 строк в секунду, и её размер вам и показывал. А если вы хотите увидеть, например, случайный счет от пользователя, мы Таким образом, вы можете увидеть, например, информацию о случайном клиенте: когда он подключился к сети, сколько времени
[08:55] и сколько ему было выставлено счетов. И это позволяет нам получить полные всё ещё смотрите, возникает очевидный вопрос: Postgres, и если да, то насколько ? И я хочу показать вам несколько реальных
[09:10] примеров, чтобы вы могли увидеть, насколько сильно отличается скорость работы, если просто включить эту единственную функцию в TimescaleDB. Итак, для этого данные, которые у меня уже есть. Итак, я просто приостановлю симуляцию и
[09:23] обычную базу данных Postgres, в которой не включена функция TimescaleDB. Так что там просто когда я, знаете, определял схему. Итак, я нажму эту кнопку, несколько минут, а затем я выполню те же запросы, те же
[09:37] объединения, все то же самое с этим другим типом данных, и вы увидите, в чем на также сколько места это занимает, потому что, как вы увидите, с Timescale DB это занимает гораздо меньше места. Итак, создание обычной базы данных Postgres завершилось, и
[09:50] выглядят вот так, и я сейчас объясню, почему. Таким образом, в обычной PostgreSQL — 2,85 ГБ, в Timescale DB — 3,47 ГБ. Причина, по которой база данных Timescale DB сейчас больше, заключается в том, что я еще не сжал таблицу. В Timescale DB есть
[10:04] встроенная функция, позволяющая сжимать любые данные временных рядов, что уменьшает их размер. Как видите, у нас уже создано восемь фрагментов, потому что здесь уже заполнены данные за восемь дней, и каждый день будет автоматически создаваться новый фрагмент, но мы
[10:17] ничего не сжимали. В отличие от обычного PostgreSQL, где таблица новая, в ней нет лишних данных, поэтому она выглядит немного меньше, и мы можем это проверить на панели мониторинга Tiger Cloud , хорошо? Итак,
[10:29] гипертаблицу и покажу вам, сколько места мы фактически экономим, когда нажмем кнопку. Это позволит сжать наши гипертаблицы. К вашему сжимать таблицы. Например, вы можете добавить
[10:44] сжимать таблицы. Я этого не сделал, потому что это симуляции, но теперь, благодаря ручному сжатию, вы через минуту увидите, сжатие только что завершилось. Из-за текущих настроек обработали только первые шесть фрагментов
[10:58] , но, как видите, фактически размер уменьшился примерно до 30% от первоначального, то есть 3,46 теперь стало 1,23 . Просто применив это два других фрагмента, то получим ещё примерно 25% прироста, и
[11:12] общий размер файла составит менее 1 ГБ. Итак, первое преимущество заключается в том, сколько места это фактически занимает при включенном сжатии. Хорошо, теперь перейдем к следующему сравнению, которое, на мой взгляд, имеет гораздо большее значение, а именно к выполнению
[11:24] выполню несколько запросов и покажу, как это выглядит в базе данных с поддержкой Timescale DB по сравнению с обычной базой данных PostgreSQL. Итак, сначала я создам панель мониторинга автопарка. Итак, эта программа
[11:36] проанализирует все показания, вычислит среднюю мощность для каждого зарядного устройства, показателей мощности. Таким образом, системе приходится просматривать практически всю таблицу, и именно этот будет выполнять каждая операционная панель мониторинга. Итак, вы увидите, что при запуске этого процесса
[11:50] как в обычной версии PostgreSQL, так и в Timescale DB. И, как вы можете видеть, если присмотреться, вот какая разница в скорости получается. Итак, обратите внимание, что обрабатывает все показания мощности из таблицы и вычисляет их как среднее значение для каждого
[12:04] зарядного устройства. В обычной версии PostgreSQL это заняло почти 17 секунд, что замедлило получение результата. В базе данных Timescale это заняло 5,4 секунды, а при использовании я также настроил в базе данных , мы получили около 1,7 секунды. Таким образом,
[12:19] , мы получили около 1,7 секунды. Таким образом, DB значительно ускоряет процесс, в 10 раз. А если я открою это, вы увидите, что сводная информация выглядит примерно так, создать представление, которое будет постоянно обновляться, чтобы
[12:32] нам было еще быстрее получать эти данные, используя данные временной шкалы . Суть непрерывного агрегирования заключается в том, что Timescale DB хранит небольшую сводную таблицу с почасовыми данными по каждому зарядному устройству, и затем
[12:44] автоматически обновляет эту сводку по мере поступления новых данных. Таким образом, вашей панели мониторинга никогда не нужно просматривать все 24 миллиона строк таблицу, что и обеспечивает высокую скорость работы. Дело в том, что сводная
[12:57] таблица практически не увеличивается в размерах, поэтому всё это будет работать чрезвычайно быстро, даже когда количество строк достигнет миллиардов. Однако, используемая со временем становится все медленнее, поскольку сжатие данных не
[13:10] каждый раз считывать всю базу данных целиком. Теперь мы можем сделать то же самое с очень похожие результаты. Как видите, здесь мы получаем очень похожие результаты. PostgreSQL, 5,3 секунды. Timescale DB, 1,9 секунды. И мы получаем один и тот же ответ в
[13:25] обоих случаях, используя запрос подобного рода. Хорошо. Теперь перейдем к следующему сравнению, которое касается спора по поводу выставленного счета, с которого я, собственно, и начал это видео. Представьте, что неверный, я не использовал столько электроэнергии, и так далее». Для решения этого вопроса
[13:39] вам понадобятся две вещи. Вам нужен счет, который хранится в таблице сессий, и зафиксированные счетчиком в момент подключения автомобиля, которые находятся в таблице показаний, содержащей около 24 миллионов строк данных. Теперь, если вы помните, я ранее
[13:52] упоминал о раздельной конфигурации, где у нас было две отдельные базы данных, и о том, как приходилось объединять множество кода, чтобы фактически извлечь эти данные. В данном случае мы можем выполнить всего один SQL-запрос, и
[14:04] счету. Например, если я возьму здесь случайную купюру, мы посмотрим на объединена. Итак, ответ мы получаем довольно быстро . У нас есть зарядном устройстве, о времени подключения, а также все
[14:19] Здесь отображаются все данные показаний датчика. Как видите, за эти 28 минут мы получили 56 показаний мощности, по одному каждые 30 секунд, что и составляет эти 56 показаний. Мы можем проверить их, подтвердить, суммировать все
[14:32] потребленные нами электроэнергию, и получить данные о киловатт-часах прямо здесь, чтобы убедиться, что счет и показания действительно совпадают. Честно говоря, если вам найти последние показания зарядного устройства , и у вас есть хороший индекс, то обычный
[14:46] понятно? И скорость вставки будет очень похожей. Теперь, когда их 20 миллионов существовать, мы всё ещё можем получать информацию, но помните, что мы говорим о легитимных сетях, которые могут содержать миллиарды, в случае
[15:00] сетей зарядки электромобилей — 630 миллиардов строк, верно? Это примерно в 35 000 раз больше, , и при таком масштабе разница в объеме памяти, о которой я говорю, — это Непрерывное агрегирование — все это не просто приятные дополнения
[15:14] , это буквально разница между работающей базой данных и той, недель, когда данные полностью заполнятся. А теперь всего две вещи, которые стоит знать. Всё, что вы только что видели, работает на самом маленьком экземпляре
[15:26] Tiger Cloud, который они предлагают. Как видите, у меня всего 2 ГБ оперативной памяти, верно? И используется самый маленький экземпляр. Также трансляция ведётся с моего компьютера через общедоступный интернет. Теперь, при желании, вы также можете настроить автоматическое перемещение всех старых данных
[15:38] в недорогие хранилища S3 вместо того, чтобы они оставались на этом устройстве, и при этом они по-прежнему будут доступны для запросов в зависимости от настроек Tiger Data. Теперь Tiger также имеет коннектор MCP, а это значит, что вы можете подключить эту
[15:50] или Cursor, и позволить искусственному интеллекту управлять ею автоматически. Таким образом, он может создавать . Именно так я и запустил этот полноценный проект, для которого Cloud автоматически добавляя данные. Вы поняли идею.
[16:05] Хорошо. Итак, честно говоря, после всего этого я пришел к выводу, что если вы собираетесь работать с данными временных рядов, то включение чего-то вроде Timescale DB — это совершенно очевидное решение. Для
[16:21] вам ничего менять не нужно . И, конечно же, если вы хотите, чтобы все в таких сервисах, как Tiger Cloud, ссылку на который я оставлю в этом видео. Если вам понравилось,
[16:34] канал, и увидимся в следующем видео! next one. >> [music]