Today, we're excited to announce that we're expanding our ecosystem support to allow you to connect PostgreSQL and TypeScript, among other programming languages, when using TimescaleDB. While PostgreSQL has always been language-agnostic, we recognize that each developer community has unique needs, patterns, and expectations regarding database integration.
Better database integration streamlines data access, enhances performance, and improves scalability, so our mission is simple: meet developers where they are and make TimescaleDB a natural extension of their existing PostgreSQL workflow—regardless of their programming language of choice.
TypeScript is a strongly typed superset of JavaScript with excellent tooling support, static type checking, and enhanced development features. It provides enhanced developer experience through early error detection, superior code organization, and seamless integration with modern frameworks.
TypeScript's connection with PostgreSQL through TimescaleDB offers developers a type-safe, maintainable approach to building data-driven applications with enhanced tooling support, static type checking, and seamless integration with modern frameworks.
How to Connect TypeScript and PostgreSQL
Daniel Starns leads our TypeScript and PostgreSQL integration. He previously worked on the core of Prisma ORM. To build the timescaledb-ts package, Daniel implemented feature parity with the timescaledb-ruby features (learn more about the TimescaleDB Ruby gem here) but followed the TypeScript style. He implemented the TimescaleDB functionality in a core library that wraps SQL and extra packages for TypeORM and Sequelize.
Getting started with TypeORM and TimescaleDB is straightforward; simply install our integration alongside your TypeORM installation:
$ npm install typeorm @timescaledb/typeorm
Then, you can use our custom TypeScript Decorators to annotate any common generic model:
import { Entity, PrimaryColumn } from 'typeorm';
+ import { Hypertable, TimeColumn } from '@timescaledb/typeorm';
+ @Hypertable({ ... })
@Entity('page_loads')
export class PageLoad {
@PrimaryColumn({ type: 'varchar' })
user_agent!: string;
+ @TimeColumn()
time!: Date;
}
Same code, with highlights: You can provide the highlighted code to TypeORM to connect to your TimescaleDB database.
The highlighted code above is what users need to provide to TypeORM to connect to TimescaleDB. The interaction behind the scenes handles the rest, such as auto-migrating hypertables.
There are several other expressive decorators, such as @ContinuousAggregate and @Rollup, that let you express and fine-tune aggregation views on top of time windows. If you find the TypeScript package helpful to connect to your PostgreSQL database, don’t forget to leave us a GitHub star! 🌟
To learn more, follow the guides in our source:
- Getting Started: a guide to getting started with TimescaleDB and TypeScript
- Working With Energy Data: a guide to working with energy data in TimescaleDB-TS
- Working With Candlesticks: a guide to working with candlestick data in TimescaleDB-TS
Outside of the engineering work, the TypeScript team has connected with the TypeORM maintainers. They have a pinned post on their Discord server and collaborated in a call with the maintainers. From here, the goal is to collaborate further with the community, create more documentation and examples, perform live streams, and educate developers through community events.
PostgreSQL Integrations: Ruby, PHP, and More
Beyond TypeScript, we've expanded our integration efforts to include several other languages. We began this journey with Ruby, creating a deeply integrated experience that feels natural to Ruby and Rails developers, including:
- Native ActiveRecord extensions for TimescaleDB features
- Simplified configuration and migration tooling
- Performance optimization patterns tailored to Ruby applications
- Comprehensive documentation with Ruby-specific examples
Building on this foundation, we've already expanded to PHP, thanks to Tobias Petry.
This approach isn't limited to specific languages—it establishes a blueprint for how TimescaleDB can integrate seamlessly with any language ecosystem through both official packages and community-led initiatives.
Let's examine the setup for each language:
- TypeScript
- Ruby
- PHP
TypeScript Setup
import { Entity, PrimaryColumn } from 'typeorm';
import { Hypertable, TimeColumn } from '@timescaledb/typeorm';
@Entity('page_loads')
@Hypertable({
compression: { // Optional compression
compress: true,
compress_orderby: 'time',
compress_segmentby: 'user_agent',
policy: {
schedule_interval: '7 days',
},
},
})
export class PageLoad {
@PrimaryColumn({ name: 'user_agent', type: 'varchar' })
userAgent!: string;
@TimeColumn()
time!: Date;
}
hypertable_options = {
time_column: 'created_at', # partition data by this column
chunk_time_interval: '1 day', # create a new table for each day
compress_segmentby: 'identifier', # columnar compression key
compress_after: '7 days', # start compression after 7 days
compress_orderby: 'created_at DESC', # compression order
drop_after: '6 months' # delete data after 6 months
}
create_table(:events, id: false, hypertable: hypertable_options) do |t|
t.timestamptz :created_at, null: false
t.string :identifier, null: false
t.jsonb :payload
end
return new class extends Migration
{
public function up(): void
{
Schema::createExtensionIfNotExists('timescaledb');
Schema::create('visits', function (Blueprint $table) {
$table->identity();
$table->bigInteger('website_id');
$table->text('url');
$table->float('duration');
$table->timestampTz('created_at');
$table->primary(['id', 'created_at']);
$table->index(['website_id', 'created_at']);
$table->timescale(
new CreateHypertable('created_at', '1 day'),
new CreateReorderPolicyByIndex('website_id', 'created_at'),
new EnableCompression(segmentBy: 'website_id'),
new CreateCompressionPolicy('3 days'),
new CreateRetentionPolicy('1 year'),
new EnableChunkSkipping('id'),
);
});
Schema::continuousAggregate('visits_agg', function(CaggBlueprint $table) {
$table->as("
SELECT
time_bucket('1 hour', created_at) AS bucket,
website_id,
url,
SUM(duration) AS duration
FROM visits
GROUP BY bucket, website_id, url
");
$table->realtime();
$table->index(['website_id','url']);
$table->timescale(
new CreateRefreshPolicy('5 minutes', '1 days', '2 hours'),
new EnableCompression(),
new CreateCompressionPolicy('2 days'),
);
});
}
};
Ruby Setup
hypertable_options = {
time_column: 'created_at', # partition data by this column
chunk_time_interval: '1 day', # create a new table for each day
compress_segmentby: 'identifier', # columnar compression key
compress_after: '7 days', # start compression after 7 days
compress_orderby: 'created_at DESC', # compression order
drop_after: '6 months' # delete data after 6 months
}
create_table(:events, id: false, hypertable: hypertable_options) do |t|
t.timestamptz :created_at, null: false
t.string :identifier, null: false
t.jsonb :payload
end
PHP Setup
return new class extends Migration
{
public function up(): void
{
Schema::createExtensionIfNotExists('timescaledb');
Schema::create('visits', function (Blueprint $table) {
$table->identity();
$table->bigInteger('website_id');
$table->text('url');
$table->float('duration');
$table->timestampTz('created_at');
$table->primary(['id', 'created_at']);
$table->index(['website_id', 'created_at']);
$table->timescale(
new CreateHypertable('created_at', '1 day'),
new CreateReorderPolicyByIndex('website_id', 'created_at'),
new EnableCompression(segmentBy: 'website_id'),
new CreateCompressionPolicy('3 days'),
new CreateRetentionPolicy('1 year'),
new EnableChunkSkipping('id'),
);
});
Schema::continuousAggregate('visits_agg', function(CaggBlueprint $table) {
$table->as("
SELECT
time_bucket('1 hour', created_at) AS bucket,
website_id,
url,
SUM(duration) AS duration
FROM visits
GROUP BY bucket, website_id, url
");
$table->realtime();
$table->index(['website_id','url']);
$table->timescale(
new CreateRefreshPolicy('5 minutes', '1 days', '2 hours'),
new EnableCompression(),
new CreateCompressionPolicy('2 days'),
);
});
}
};
Why Language-Specific Integrations Matter
While TimescaleDB works with any language that connects to PostgreSQL, we believe in going beyond basic compatibility. Language-specific integrations offer significant advantages:
- Idiomatic implementations that align with community best practices
- Enhanced developer experience through familiar patterns and tooling
- Targeted performance optimizations for language-specific ORMs and drivers
- Relevant documentation with contextual examples and use cases
Our goal isn't merely compatibility with your technology stack—we aim to become an essential, natural extension of it.
Want to create your own integration? Check out our comprehensive integration guide.
Join Us: We're Supporting Community Integrations
We're actively seeking developers interested in building and maintaining TimescaleDB integrations for their language communities. Whether you're passionate about Python, Go, Rust, PHP, JavaScript, Java, .NET, or any other ecosystem, we want to support your efforts.
Here's what we offer to community integration maintainers:
- Dedicated technical support from our DevRel team
- Co-marketing opportunities to showcase your integration
- Collaborative documentation development
- Conference and meetup sponsorship for community education
- Early access to upcoming features
If you're interested, book a Technical Office Hours call with me (Jônatas, developer advocate at Timescale), and let's begin the conversation!
Real-World Impact: Performance Workshop Series
As part of this initiative, I presented "The PostgreSQL Performance Workshop for Rubyists" at a few conferences, including Tropical on Rails in São Paulo, Brazil. This workshop demonstrated our commitment to education across language communities, with content that is adaptable to other languages.
The workshops covered:
- Advanced query optimization techniques
- Effective time-series data modeling
- Scaling strategies for high-throughput applications
- PostgreSQL internals that impact application performance
To provide more educational resources, we're already bringing Ruby to our blog and showing the real-world impact of these integrations. Check out this article from an early developer adopter of the timescaledb gem on how to set up a dashboard for global energy data analytics.
Our Roadmap: What's Next
We're approaching this ecosystem expansion methodically. Throughout this process, you can expect to see us document our approach, share best practices, and create reusable patterns that make TimescaleDB integration consistent across languages while remaining idiomatic to each.
Community Engagement and Support
We're committed to fostering a strong community around TimescaleDB and encouraging broader ecosystem development. Here's how we plan to engage and support developers:
- Open collaboration : We welcome developers to actively participate in shaping TimescaleDB integrations through ideas, expertise, and code contributions.
- Community events : We'll host and participate in events and workshops to connect with developers and provide hands-on support.
- Project sponsorship : We're sponsoring open-source projects that align with our mission of making time-series data accessible.
- Developer support : Our team offers timely assistance to developers integrating TimescaleDB into their projects through dedicated Office Hours.
Through these initiatives, we aim to build an inclusive community where developers can learn, collaborate, and create innovative applications with TimescaleDB.
Get Involved
At Timescale, we believe real-time analytics is essential for any data-driven business, which means time-series data is everywhere. Developers across all language communities deserve high-quality tools for handling this demanding workload. By expanding our ecosystem support and embracing community-led integrations, we're creating a more inclusive and powerful platform.
Join us in this mission! Here’s how you can get involved:
- Join our community and connect with the Ecosystem team.
- Check out our integration development guidelines .
- Book a session with our technical team.
Are you building an integration for TimescaleDB in your preferred language? We'd love to hear about it! Share your project or reach out to our Ecosystem team directly.
Top comments (0)