Skip to content

Parse Server compatibility with Serverless environment #7938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
3 tasks done
Moumouls opened this issue Apr 14, 2022 · 19 comments
Open
3 tasks done

Parse Server compatibility with Serverless environment #7938

Moumouls opened this issue Apr 14, 2022 · 19 comments
Labels
type:feature New feature or improvement of existing feature

Comments

@Moumouls
Copy link
Member

New Feature / Enhancement Checklist

Current Limitation

I'm currently investigating the usage of Parse Server in a serverless env. The current tested setup is:

  • Parse Server with Defined Schema and GraphQL packaged in a Docker image
  • This Docker image is used on Google Cloud Run, with CPU allocated only during init/requests
  • Use MongoDB Atlas Serverless as the database

Refactors/workarounds:

  • Parse Server express app call listen() too early (before serverStartComplete), so request cloud be routed to parse-server with a partial/incomplete initialization. For example, defined schema migration could not be finished. A workaround is to call a new "parse.expressApp.listen(1339)" on a different port in serverStartComplete to tell the serverless env (GCP Cloud Run) to start sending requests to the 1339 port.

Errors:

Limitations:

  • On many serverless env background tasks (actions performed after a request is returned by the server): like Parse.Jobs will not work
  • LiveQuery needs an additional setup (not tested)

Stats:

  • Parse Server with defined schema start in 7sec when Parse needs to create all schema (should only happen one time)
  • Parse Server with defined schema start in 3-4sec when Parse is already initialized (defined schema done, DB init done, etc...), this is the real cold start if Parse Server scale to 0 instances.

Feature / Enhancement Description

The cold start is mainly related to dependency size.
To reduce cold start we need to start some code splitting. All adapters should be moved out of parse-server. Developers should be able to only import wanted adapters/servers, like LiveQuery, GraphQL server, PostgresAdapter, etc...

Then some tiny cache optimization could help to make the parse-server start under maybe 1-2sec.

Example Use Case

Fully serverless usage (with mongo serverless) to allow Parse developers to leverage Serverless computing like:

  • No infra management
  • Super scalable
  • Scale to Zero
  • Huge cloud cost reduction

Alternatives / Workarounds

None

3rd Party References

Cloud providers that support scale to zero container instances

https://cloud.google.com/run
https://www.scaleway.com/en/serverless-containers/
https://docs.microsoft.com/en-us/azure/container-apps/
https://aws.amazon.com/ecs/

Database provider with serverless (pay as you go) pricing
https://www.mongodb.com/cloud/atlas/serverless

@parse-github-assistant
Copy link

Thanks for opening this issue!

  • 🎉 We are excited about your ideas for improvement!

@mtrezza
Copy link
Member

mtrezza commented Apr 14, 2022

See #483

@mtrezza mtrezza added the type:question Support or code-level question label Apr 14, 2022
@Moumouls
Copy link
Member Author

Note: I'm currently not investigating proprietary serverless environments like AWS Lambda/Cloudflare Workers/Vercel serverless. Since it needs specific adaptations/bundling, it's not easily testable in a local env. From my point of view, it's a less standard approach.

Docker helps to get some execution abstraction.

I'm currently focusing on making a parse-server at least compatible to run in a container on a serverless orchestrator: like GCP Cloud Run, Knative.

I'm also focusing on containers since Knative is now part of CNCF, and could be the next cloud standard (like Kubernetes ) to deploy serverless containers across cloud providers: https://www.forbes.com/sites/janakirammsv/2022/03/06/cncf-accepts-knative-projectwhat-does-it-mean-to-the-cloud-native-ecosystem/?sh=72413dfe174b

@mtrezza
Copy link
Member

mtrezza commented Apr 14, 2022

So is this still a general discussion? In that case it should continue in our community forum. We use GitHub to track concrete issues and feature suggestions.

@Moumouls
Copy link
Member Author

It's not a general discussion, it's an issue, and I will work on a PR to fix the app. listen to the issue.
I'll also work on a distinct pr to fix the collation issue for Mongo Serverless.

@mtrezza
Copy link
Member

mtrezza commented Apr 15, 2022

What you are describing seems to be a refactoring of Parse Server that won't be done with a few small PRs. These seems to be several individual issues (adapters, cache, collation), each of which will likely require its own GH issue and discussion. Could you make a roadmap for this with a TODO list to see for which points we need to discuss in more depth?

@Moumouls
Copy link
Member Author

Moumouls commented Apr 20, 2022

@mtrezza

Roadmap:

Minimum compatibility requirements

  1. Fix errors (developers do not have workarounds):
  • feat: allow to disable collation (case-insensitivity) on User queries/indexes (email/username)
  1. Parse Server listens too early
  • feat: add a new "startCompletePort" option to be handle correctly public requests (from a internet/balancer) once parse server startComplete resolve. We need an additional port since internal parse-server code, developers' code inside before/afterMigration, and startServerComplete could use Parse Node JS SDK that internally uses a serverUrl.

At this point Parse Server (without livequery and Parse Jobs) should be able to run in a containerized serverless env out of the box (for example on Cloud Run GCP)

Performance improvement (road to 1-2 sec cold start)

  1. Code splitting
  • feat: move out adapters of the parse-server package, and allow developers to only install and provide needed adapters, to reduce nodeJS require time currently approximatively 2sec
  1. Init speed up
  • feat: use the hash (SHA1) mechanism on schema and some configs to easily detect changes, I think parse-server could be optimized and can reduce init time.
  1. Dynamic module loading investigation
  • feat: some modules of parse could be required dynamically once needed, for example, an auth provider, should be loaded only if a request uses it. The server should not load/require all the code by default at startup time.

Support feature not "Serverless Friendly" like LiveQuery, Parse Jobs

  • feat: test and support LiveQuery limitations on serverless
  • feat: (i need some investigation on this) add "serverless" Parse Job option, if activated, when a job is triggered from a client (ex: parse-dashboard), to be able to handle the background job, parse-server will need to call itself or another parse-server instance via parseServerJobPublicURL, since many serverless environments only attribute CPU during a request (like GCP). The new jobServerlessEndpoint need to await job completion before returning an HTTP response, to keep access to the CPU. The parseServerJobPublicURL could be also used to allow developers to run Jobs on a dedicated remote parse-server, not running in serverless env.

@Moumouls
Copy link
Member Author

@mtrezza we can split this one into many issues. I think we should also keep this issue open to tracking the work progress.

I'll work on point 1 and 2 may be the next week?

@mtrezza
Copy link
Member

mtrezza commented Apr 20, 2022

Yes, this should be split into smaller PRs as much as possible because large, monolithic PRs are more difficult to manage and take more time to get merged. We can keep this issue open to track the progress; maybe you want to move a compact TODO list of your roadmap to the post at the very top and add checkboxes and PR references to each one so everyone can easily see the status of this.

@mtrezza mtrezza added type:feature New feature or improvement of existing feature and removed type:question Support or code-level question labels Apr 20, 2022
@Moumouls
Copy link
Member Author

Moumouls commented May 3, 2022

Just for reference, the readiness probe, exposing the server to public traffic needs to be handled by the developer.

Linked comment : #7914 (comment)

The #7914 will allow developers to design graceful start easily using startAsync or serverStartComplete thanks to @dblythy

@Moumouls
Copy link
Member Author

Moumouls commented May 3, 2022

@mtrezza what do you think about adding a section on the docs about some tips for a graceful start in environments like PM2, GCP Could Run, Kubernetes, etc...

@mtrezza
Copy link
Member

mtrezza commented May 3, 2022

Sure, please feel free to open a PR.

@stewones
Copy link
Contributor

👀 I'm also interested in serverless hosting, specifically Atlas Serverless... I'm curious to know what the status of this project is.

@Moumouls
Copy link
Member Author

Moumouls commented Nov 14, 2022

Hi @stewones, I'm running successfully many parse servers with MongoDB Atlas Serverless (6.1). Once correct indexes are added it works like a charm with excellent cost efficiency.

To work with MongoDB serverless some PRs are needed like this one: #8042

The best and easiest option to run parse-server in serverless env is Google Cloud Run using a Docker container.

@mtrezza once needed PR to are merged I can push a repo example (with terraform file example) to deploy Parse Server fully serverless on Google Cloud Run and Mongo Atlas Serverless for developers interested in running parse-server as Serverless.

The repo example could be coupled to a documentation page/blog post maybe

@Moumouls
Copy link
Member Author

Moumouls commented Nov 14, 2022

it could be a good blog post for Parse V6: "Parse Server goes fully serverless with Mongo Atlas Serverless and Google Cloud Run"

@dblythy do you have some suggestions here ?

@dblythy
Copy link
Member

dblythy commented Nov 14, 2022

It sounds like a good idea. Mongo Atlas Serverless sounds exciting and I'm keen to see how it compares in price vs my current solution which is AWS EB.

@Moumouls
Copy link
Member Author

Moumouls commented Nov 14, 2022

I'm keen to see how it compares in price

On MongoDB Serverless it depends a lot of indexes, a poorly indexed query will produce a lot RPU, my current strategy is to "over-index" (creating many indexes on possible queries) since storage is so much cheaper than RPU/WPU.

But I can easily say that once indexes are correctly configured, scaling, performance, and cost of MongoDB Serverless are really impressive.

And Parse Server on Cloud Run with a Google Cloud task that keeps at least 1 server idle, it's also really cost-efficient.

@dblythy

For an app with invariant traffic and 10k of users you can easily run Parse Server on Cloud Run + Mongo Atlas Serverless for like 10$/month (or less) (but it really depends of the app, and optimization, caches etc...). Serverless is not magic, just super efficient when it's correctly used.

@matheusfrozzi
Copy link

@Moumouls did you publish the tutorial to run the parse server with google cloud run? Didn't find it anywhere!

Thanks

@Moumouls
Copy link
Member Author

Hi @matheusfrozzi , it's quite easy to run Parse Server in Google Cloud Run, Google Cloud Run is standard and you just need to start your parse server and makes sure that it listen on port 80.

Parse Server have a little bit of cold start, if you want to prevent a cold start you can use common tricks like using a Google Cloud Scheduler to ping each min your Google Cloud Service.

Be aware that on Google Cloud Run by default it's not easy to use Live Query, it needs way more setup.

About the cache, since i've many small parse server instances, i don't care about a centralized cache, the in memory cache ( default of parse server) do the job.

Again a big warning on background tasks in Google Cloud Run when you use the pricing with CPU only active on the request. Parse Cloud Jobs will not work correctly by default.

To run background task correctly on Google Cloud Run ( it's not related to Parse or NodeJS).

You need this kind of flow:

  • The client call your server
  • Your server create a Google Task with the needed payload and the target http should be the Google Cloud Run url itself
  • Parse Server or you custom endpoint will return a 200 or some status to the client
  • Google Task will call your server, and Google Cloud Run X Google Task support a background task of a maximum of 1h ( if you need more you need to use recursive Google Tasks)
  • Once the task is finished your client can refresh the UI, or you can send a notification, it's up to you to choose the appropriate method to notify the client ( client interval polling, sms, email, websockets etc...)

@parse-community parse-community deleted a comment Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature New feature or improvement of existing feature
Projects
None yet
Development

No branches or pull requests

5 participants