R
Railway10mo ago
Yoginth

Getting [ioredis] Unhandled error event: ReplyError: ERR max number of clients reached

Any ideas why?
Solution:
youre trying to exceed the max clients allowable, this is a limitation of redis itself and not due to anything railway related. make sure to close connections when youre done with them. maybe look into how you could go about using pooling instead of a new client for every request....
Jump to solution
25 Replies
Percy
Percy10mo ago
Project ID: N/A
Yoginth
Yoginth10mo ago
No description
Brody
Brody10mo ago
can i see your connection constructor please?
Yoginth
Yoginth10mo ago
import { Redis } from 'ioredis';

const createRedisClient = () => {
return new Redis(process.env.REDIS_URL!, {
family: 6
});
};

export default createRedisClient;
import { Redis } from 'ioredis';

const createRedisClient = () => {
return new Redis(process.env.REDIS_URL!, {
family: 6
});
};

export default createRedisClient;
and we consume something like this
import { Errors } from '@hey/data/errors';
import logger from '@hey/lib/logger';
import catchedError from '@utils/catchedError';
import { SWR_CACHE_AGE_1_MIN_30_DAYS } from '@utils/constants';
import createRedisClient from '@utils/createRedisClient';
import prisma from '@utils/prisma';
import type { Handler } from 'express';

export const get: Handler = async (req, res) => {
const { id } = req.query;

if (!id) {
return res.status(400).json({ success: false, error: Errors.NoBody });
}

try {
const redis = createRedisClient();
const cache = await redis.get(`preferences:${id}`);

if (cache) {
logger.info('Profile preferences fetched from cache');
return res
.status(200)
.setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS)
.json({ success: true, cached: true, result: JSON.parse(cache) });
}

const [preference, pro, features] = await prisma.$transaction([
prisma.preference.findUnique({ where: { id: id as string } }),
prisma.pro.findFirst({ where: { profileId: id as string } }),
prisma.profileFeature.findMany({
where: {
profileId: id as string,
enabled: true,
feature: { enabled: true }
},
select: { feature: { select: { key: true } } }
})
]);

const response = {
preference,
pro: { enabled: Boolean(pro) },
features: features.map((feature: any) => feature.feature?.key)
};

await redis.set(`preferences:${id}`, JSON.stringify(response));
logger.info('Profile preferences fetched from DB');

return res
.status(200)
.setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS)
.json({
success: true,
result: response
});
} catch (error) {
return catchedError(res, error);
}
};
import { Errors } from '@hey/data/errors';
import logger from '@hey/lib/logger';
import catchedError from '@utils/catchedError';
import { SWR_CACHE_AGE_1_MIN_30_DAYS } from '@utils/constants';
import createRedisClient from '@utils/createRedisClient';
import prisma from '@utils/prisma';
import type { Handler } from 'express';

export const get: Handler = async (req, res) => {
const { id } = req.query;

if (!id) {
return res.status(400).json({ success: false, error: Errors.NoBody });
}

try {
const redis = createRedisClient();
const cache = await redis.get(`preferences:${id}`);

if (cache) {
logger.info('Profile preferences fetched from cache');
return res
.status(200)
.setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS)
.json({ success: true, cached: true, result: JSON.parse(cache) });
}

const [preference, pro, features] = await prisma.$transaction([
prisma.preference.findUnique({ where: { id: id as string } }),
prisma.pro.findFirst({ where: { profileId: id as string } }),
prisma.profileFeature.findMany({
where: {
profileId: id as string,
enabled: true,
feature: { enabled: true }
},
select: { feature: { select: { key: true } } }
})
]);

const response = {
preference,
pro: { enabled: Boolean(pro) },
features: features.map((feature: any) => feature.feature?.key)
};

await redis.set(`preferences:${id}`, JSON.stringify(response));
logger.info('Profile preferences fetched from DB');

return res
.status(200)
.setHeader('Cache-Control', SWR_CACHE_AGE_1_MIN_30_DAYS)
.json({
success: true,
result: response
});
} catch (error) {
return catchedError(res, error);
}
};
@Brody
Brody
Brody10mo ago
no need for the ping please
Yoginth
Yoginth10mo ago
here is the prod endpoint breaking, aka ~ millions of request broke from yesterday night https://api.hey.xyz/preference/getPreferences?id=0x01b69c it works fine with local redis
Brody
Brody10mo ago
i mean where you testing millions of requests locally too haha but what version of redis are you using locally?
Yoginth
Yoginth10mo ago
its 7.2.3 on local im not testing millions of req locally, but for like a week its fine on railway it broke suddenly even we didnt push any changes
Brody
Brody10mo ago
are you using a depricated redis plugin or a redis service on railway?
Yoginth
Yoginth10mo ago
no, not using any plugins its raw redis provided by railway
Yoginth
Yoginth10mo ago
imo its not with the code, i see same error on medis ui too
No description
Brody
Brody10mo ago
not quite what i asked, but i understand the plugin word i used can cause misinterpretation, so let me rephrase. does your redis database have a volume?
Yoginth
Yoginth10mo ago
yup yup lemme grab screenshot
Yoginth
Yoginth10mo ago
No description
Brody
Brody10mo ago
this is the max client count
No description
Want results from more Discord servers?
Add your server