W
Wasp3mo ago
Sven

Server 500 response Timed out fetching a new connection from the connection pool.

2025-01-26T09:07:40.152 app[d890426c46e328] ams [info] POST /operations/get-tracked-product-stats 500 10027.476 ms - 148 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] PrismaClientKnownRequestError: 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] Invalid prisma.salesData.findMany() invocation: 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] Timed out fetching a new connection from the connection pool. More info: http://pris.ly/d/connection-pool (Current connection pool timeout: 10, connection limit: 3) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at Ln.handleRequestError (/app/node_modules/@prisma/client/runtime/library.js:121:7753) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at Ln.handleAndLogRequestError (/app/node_modules/@prisma/client/runtime/library.js:121:7061) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at Ln.request (/app/node_modules/@prisma/client/runtime/library.js:121:6745) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at async l (/app/node_modules/@prisma/client/runtime/library.js:130:9633) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at <anonymous> (/app/src/actions/.ts:70:25) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at async Promise.all (index 27) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at $2 (/app/src/actions/.ts:68:17) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at <anonymous> (/app/.wasp/build/server/src/middleware/operations.ts:14:24) 2025-01-26T09:07:40.198 app[d890426c46e328] ams [info] at <anonymous> (/app/.wasp/out/sdk/wasp/server/utils.ts:26:5)
Connection pool | Prisma Documentation
Prisma ORM's query engine creates a connection pool to store and manage database connections.
12 Replies
kapa.ai
kapa.ai3mo ago
Hi @Sven. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the error message you've provided, it appears you're encountering a database connection issue in your Wasp application. This is a common problem that can occur when the database connection pool is exhausted or when there are network issues. Let's break down the error and provide some potential solutions. The key part of the error message is:
Timed out fetching a new connection from the connection pool. More info: <http://pris.ly/d/connection-pool> (Current connection pool timeout: 10, connection limit: 3)
Timed out fetching a new connection from the connection pool. More info: <http://pris.ly/d/connection-pool> (Current connection pool timeout: 10, connection limit: 3)
This indicates that Prisma, which Wasp uses for database operations, was unable to establish a new connection within the specified timeout period. The connection pool is limited to 3 connections, and the timeout is set to 10 seconds. Here are some steps you can take to address this issue: 1. Increase connection pool size: You may need to increase the number of connections in your pool. This can be done by modifying your Prisma configuration. However, in Wasp, you typically don't directly modify the Prisma configuration. 2. Optimize database queries: Review your database queries, especially in the getTrackedProductStats operation, to ensure they're efficient and not holding connections open for too long. 3. Check database load: Ensure your database isn't overloaded. If it's struggling to handle the current load, you might need to scale up your database resources. 4. Implement retry logic: For operations that might fail due to connection issues, you can implement retry logic. Wasp provides error handling capabilities for this purpose. 5. Use HttpError for better error handling: As mentioned in the Wasp documentation on error handling, you can use HttpError to provide more meaningful error messages to the client. For example:
import { HttpError } from 'wasp/server'

export const getTrackedProductStats = async (args, context) => {
try {
// Your database operation here
} catch (error) {
throw new HttpError(
500,
"Database connection error",
{ details: error.message }
)
}
}

import { HttpError } from 'wasp/server'

export const getTrackedProductStats = async (args, context) => {
try {
// Your database operation here
} catch (error) {
throw new HttpError(
500,
"Database connection error",
{ details: error.message }
)
}
}

6. Check your deployment environment: If you're deploying on a platform like Fly.io, make sure your database is properly attached to your application. There have been issues reported where database attachment failed during deployment. 7. Monitor and log errors: Implement proper logging in your application to help diagnose these issues more easily in the future. If the problem persists after trying these solutions, you may need to dive deeper into your specific application setup and database configuration. The Wasp community on Discord or GitHub issues might be able to provide more tailored advice if you can share more details about your application structure and deployment environment. Remember, when dealing with database connection issues, it's important to balance between having enough connections to handle your application's needs and not overwhelming your database server with too many open connections. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Sven, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Sven
SvenOP3mo ago
anyone know how i can use fly and increase the connection amount? @ me
miho
miho3mo ago
How many req/s to you have to your backend? Are you fetching a lot of data with your queries? You can try to fix things this way (by reducing the load on the server and reducing your query size). You aren't able to modify the Prisma settings until we implement https://github.com/wasp-lang/wasp/issues/2116 - this is something we'll prioritise in now in Q1
GitHub
Prisma setup hook · Issue #2116 · wasp-lang/wasp
Prisma supports client extensions: https://www.prisma.io/docs/orm/prisma-client/client-extensions which for: You can use Prisma Client extensions to add functionality to your models, result objects...
miho
miho3mo ago
I see in the log that it took 10s for DB to respond - this sounds to me like you are trying to fetch too much in one go. I'd maybe try chunking the data into multiple batches or smth like that.
Sven
SvenOP2mo ago
datasource db { provider = "postgresql" url = env("DATABASE_URL") connection_limit = 10 } is htis possible in schema.prisma not sure
Sven
SvenOP2mo ago
No description
Sven
SvenOP2mo ago
also not sure how to fix this issue i stated above (in initial message), it happens only when i do a certain query i created with wasp.
export const getTrackedProducts: GetTrackedProducts<void, Products[]> = async (args, context) => {
if (!context.user) {
throw new HttpError(401,'User is not authenticated');
}

if (!context.user.isAdmin) {
// Check for subscription status and plan restrictions for non-admin users
if (context.user.subscriptionStatus === 'past_due') {
throw new HttpError(403, 'Uw abonnement is verlopen. Werk uw betalingsgegevens bij.');
}

if (context.user.subscriptionPlan !== 'max' && context.user.subscriptionPlan !== 'boost') {
throw new HttpError(403, 'Uw abbonoment laat deze functie niet toe.');
}
}



const trackedProducts = await context.entities.UserTrackedProducts.findMany({
where: { userId: context.user.id },
select: { productId: true },
});

const productIds = trackedProducts.map((track) => track.productId);

return context.entities.Products.findMany({
where: { id: { in: productIds } },
orderBy: { id: 'asc' },
});
};
export const getTrackedProducts: GetTrackedProducts<void, Products[]> = async (args, context) => {
if (!context.user) {
throw new HttpError(401,'User is not authenticated');
}

if (!context.user.isAdmin) {
// Check for subscription status and plan restrictions for non-admin users
if (context.user.subscriptionStatus === 'past_due') {
throw new HttpError(403, 'Uw abonnement is verlopen. Werk uw betalingsgegevens bij.');
}

if (context.user.subscriptionPlan !== 'max' && context.user.subscriptionPlan !== 'boost') {
throw new HttpError(403, 'Uw abbonoment laat deze functie niet toe.');
}
}



const trackedProducts = await context.entities.UserTrackedProducts.findMany({
where: { userId: context.user.id },
select: { productId: true },
});

const productIds = trackedProducts.map((track) => track.productId);

return context.entities.Products.findMany({
where: { id: { in: productIds } },
orderBy: { id: 'asc' },
});
};
export const getTrackedProductStats: GetTrackedProductStats<{ timeFrame: string }, { productId: number, avgPrice: number, totalSales: number, totalRevenue: number }[]> = async (args, context) => {
const { timeFrame } = args;
const days = timeFrame === '3m' ? 90 : 30;

if (!context.user) {
throw new Error('User is not authenticated');
}
if (!context.user.isAdmin) {
// Check for subscription status and plan restrictions for non-admin users
if (context.user.subscriptionStatus === 'past_due') {
throw new HttpError(403, 'Uw abonnement is verlopen. Werk uw betalingsgegevens bij.');
}

if (context.user.subscriptionPlan !== 'max' && context.user.subscriptionPlan !== 'boost') {
throw new HttpError(403, 'Uw abbonoment laat deze functie niet toe.');
}
}

// Get the IDs of products tracked by the user
const trackedProducts = await context.entities.UserTrackedProducts.findMany({
where: { userId: context.user.id },
select: { productId: true },
});

const productIds = trackedProducts.map((track) => track.productId);

// Get sales data only for tracked products
const stats = await Promise.all(
productIds.map(async (productId) => {
const salesData = await context.entities.SalesData.findMany({
where: { productId },
orderBy: { id: 'desc' },
take: days,
});

const avgPrice = salesData.length > 0
? salesData.reduce((sum, data) => sum + (data.avgPrice || 0), 0) / salesData.length
: 0;
const totalSales = salesData.reduce((sum, data) => sum + (data.totalSales || 0), 0);
const totalRevenue = salesData.reduce((sum, data) => sum + (data.totalRevenue || 0), 0);

return {
productId,
avgPrice,
totalSales,
totalRevenue,
};
})
);

return stats;
};
export const getTrackedProductStats: GetTrackedProductStats<{ timeFrame: string }, { productId: number, avgPrice: number, totalSales: number, totalRevenue: number }[]> = async (args, context) => {
const { timeFrame } = args;
const days = timeFrame === '3m' ? 90 : 30;

if (!context.user) {
throw new Error('User is not authenticated');
}
if (!context.user.isAdmin) {
// Check for subscription status and plan restrictions for non-admin users
if (context.user.subscriptionStatus === 'past_due') {
throw new HttpError(403, 'Uw abonnement is verlopen. Werk uw betalingsgegevens bij.');
}

if (context.user.subscriptionPlan !== 'max' && context.user.subscriptionPlan !== 'boost') {
throw new HttpError(403, 'Uw abbonoment laat deze functie niet toe.');
}
}

// Get the IDs of products tracked by the user
const trackedProducts = await context.entities.UserTrackedProducts.findMany({
where: { userId: context.user.id },
select: { productId: true },
});

const productIds = trackedProducts.map((track) => track.productId);

// Get sales data only for tracked products
const stats = await Promise.all(
productIds.map(async (productId) => {
const salesData = await context.entities.SalesData.findMany({
where: { productId },
orderBy: { id: 'desc' },
take: days,
});

const avgPrice = salesData.length > 0
? salesData.reduce((sum, data) => sum + (data.avgPrice || 0), 0) / salesData.length
: 0;
const totalSales = salesData.reduce((sum, data) => sum + (data.totalSales || 0), 0);
const totalRevenue = salesData.reduce((sum, data) => sum + (data.totalRevenue || 0), 0);

return {
productId,
avgPrice,
totalSales,
totalRevenue,
};
})
);

return stats;
};
this is the query
Sven
SvenOP2mo ago
No description
Sven
SvenOP2mo ago
sorrty for the lot of data i send but the images are what happens when i go to the page that does the query that makes this stuff crash or stop and the code is the query
miho
miho5w ago
We use all the properties you defined in the datasource 👍 you can verify that by looking at the .wasp/out/db/schema.prisma file (that's the final Prisma file Wasp uses) In your case from above... I'd maybe try to removing await Promise.all( and awaiting stats one by one and see if it helps. What is the size of the dataset? trackedProducts is 10s or 1000s or 10000s of items per user? This is not strictly related to Wasp and I can't really offer that deep insights, as I said, this is more analytics / data / database optimisation problem for which you can find good resources online 🙂
Sven
SvenOP5w ago
10s but the stats is really big 100.000 total entries for example and 1000s per user

Did you find this page helpful?