Features
Docs
CLI
Benchmarks
Examples

© 2024 MoroJs

Performance Tuning

Optimize your MoroJS applications for maximum performance. Learn caching strategies, database optimization, and monitoring techniques for production workloads.

Performance That Just Works

Optimize your application with built-in caching, compression, and monitoring.
Database optimization and query monitoring included.

It's This Simple

Enable caching with one line

typescript

1import { createApp } from '@morojs/moro';
2
3const app = createApp({
4  cors: true,
5  compression: true, // Built-in performance feature
6  helmet: true
7});
8
9// Built-in caching with chainable API
10app.get('/users')
11  .cache({ ttl: 60, key: 'users-list' }) // Cache for 60 seconds
12  .handler((req, res) => {
13    const users = getAllUsers(req.query);
14    return { success: true, data: users };
15  });

Why Performance Matters

Without proper optimization, you're wasting resources, slowing down responses, and increasing costs. With MoroJS, you get caching, compression, and monitoring automatically.

Traditional performance optimization requires manual setup. We handle that automatically.

Without Optimization

  • Slow response times
  • No caching
  • No performance monitoring
  • Higher server costs

With MoroJS

  • Fast response times
  • Built-in caching
  • Performance monitoring
  • Lower server costs

Why It Makes Sense

Fast

Built-in caching and compression for optimal performance

Monitored

Performance monitoring and slow query detection

Optimized

Database query optimization and connection pooling

How It Works

MoroJS provides built-in performance features including caching, compression, and monitoring. You can enable caching per route, monitor query performance, and optimize database connections with minimal configuration.

Performance Monitoring

Simple Performance Monitoring

typescript

1import { createApp } from '@morojs/moro';
2
3const app = createApp({
4  cors: true,
5  compression: true, // Built-in performance feature
6  helmet: true
7});
8
9// Simple performance middleware (custom implementation)
10app.use((req, res, next) => {
11  const start = Date.now();
12  
13  // Add request timing
14  req.startTime = start;
15  
16  // Override res.json to add timing header
17  const originalJson = res.json;
18  res.json = function(data) {
19    const duration = Date.now() - start;
20    res.setHeader('X-Response-Time', `${duration}ms`);
21    
22    // Log slow requests
23    if (duration > 1000) {
24      console.warn(`Slow request: ${req.method} ${req.path} - ${duration}ms`);
25    }
26    
27    return originalJson.call(this, data);
28  };
29  
30  next();
31});
32
33// Health check with performance metrics
34app.get('/health', (req, res) => {
35  const memUsage = process.memoryUsage();
36  
37  return {
38    status: 'healthy',
39    timestamp: new Date().toISOString(),
40    uptime: process.uptime(),
41    memory: {
42      rss: Math.round(memUsage.rss / 1024 / 1024) + 'MB',
43      heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024) + 'MB',
44      heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024) + 'MB'
45    },
46    nodeVersion: process.version
47  };
48});

Advanced Caching Strategies

Simple Caching with MoroJS

typescript

1// Built-in caching with chainable API (actual implementation)
2app.get('/users')
3  .query(z.object({
4    limit: z.coerce.number().default(10),
5    search: z.string().optional()
6  }))
7  .cache({ ttl: 60, key: 'users-list' }) // Cache for 60 seconds
8  .handler((req, res) => {
9    const users = getAllUsers(req.query);
10    return { success: true, data: users };
11  });
12
13// Dynamic cache keys
14app.get('/users/:id')
15  .cache({ ttl: 300, key: (req) => `user-${req.params.id}` }) // 5 minutes
16  .handler((req, res) => {
17    const user = getUserById(req.params.id);
18    return { success: true, data: user };
19  });
20
21// Configuration-driven caching
22app.get('/data')
23  .cache({ ttl: app.getConfig().modules.cache.defaultTtl })
24  .handler((req, res) => {
25    return { data: getExpensiveData() };
26  });
27
28// External Redis caching (for advanced use cases)
29import Redis from 'redis';
30
31const redis = Redis.createClient({ url: process.env.REDIS_URL });
32await redis.connect();
33
34// Custom Redis middleware
35const redisCache = (ttl) => {
36  return async (req, res, next) => {
37    const cacheKey = `cache:${req.method}:${req.path}`;
38    
39    try {
40      const cached = await redis.get(cacheKey);
41      if (cached) {
42        res.setHeader('X-Cache', 'HIT');
43        return res.json(JSON.parse(cached));
44      }
45      
46      const originalJson = res.json;
47      res.json = function(data) {
48        redis.setEx(cacheKey, ttl, JSON.stringify(data));
49        res.setHeader('X-Cache', 'MISS');
50        return originalJson.call(this, data);
51      };
52      
53      next();
54    } catch (error) {
55      console.error('Cache error:', error);
56      next();
57    }
58  };
59};
60
61// Use Redis caching
62app.get('/expensive-data', redisCache(300), (req, res) => {
63  const data = performExpensiveOperation();
64  return { success: true, data };
65});

Database Optimization

Query Optimization

typescript

1// Query performance monitoring
2const queryMonitor = {
3  slowQueryThreshold: 1000, // 1 second
4  
5  async logSlowQuery(query: string, params: any[], duration: number) {
6    if (duration > this.slowQueryThreshold) {
7      console.warn('Slow query detected:', {
8        query,
9        params,
10        duration: `${duration}ms`,
11        timestamp: new Date().toISOString()
12      });
13      
14      // Send to monitoring service
15      await sendMetric('slow_query', {
16        query_hash: hashQuery(query),
17        duration,
18        timestamp: Date.now()
19      });
20    }
21  }
22};
23
24// Optimized database middleware
25app.use(async (context, next) => {
26  const originalQuery = context.db.query;
27  
28  context.db.query = async (sql: string, params: any[] = []) => {
29    const start = Date.now();
30    
31    try {
32      const result = await originalQuery.call(context.db, sql, params);
33      const duration = Date.now() - start;
34      
35      await queryMonitor.logSlowQuery(sql, params, duration);
36      
37      return result;
38    } catch (error) {
39      console.error('Database query error:', { sql, params, error: error.message });
40      throw error;
41    }
42  };
43  
44  await next();
45});
46
47// Connection pool optimization
48app.get('/users/:id', {
49  handler: async ({ params, db }) => {
50    // Use read replica for read-only queries
51    const user = await db.replica.query(
52      'SELECT id, name, email FROM users WHERE id = $1',
53      [params.id]
54    );
55    
56    if (!user[0]) {
57      return { error: 'User not found' };
58    }
59    
60    // Use cache for frequently accessed data
61    const cacheKey = `user_profile:${params.id}`;
62    let profile = await cache.get(cacheKey);
63    
64    if (!profile) {
65      profile = await db.replica.query(
66        'SELECT bio, avatar_url, preferences FROM user_profiles WHERE user_id = $1',
67        [params.id]
68      );
69      
70      await cache.set(cacheKey, profile[0], { ttl: '15m' });
71    }
72    
73    return {
74      ...user[0],
75      profile: profile[0]
76    };
77  }
78});

Next Steps