In the last few releases the size of the dependencies has skyrocketed. The libmoncrypto added 20 MB of runtimes (linux and osx is 10 MB each) and taking a hard dependency on AWS.SecurityToken added another 2 MB. I don’t use any of the functionality that these new dependencies bring, but my app went from 17 MB to over 40 MB. Could these have not been moved into separate assemblies and only be required when the functionality was required? The dependency on the AWS framework is particularly egregious.
Hi @James_Moring. Welcome to the community.
That’s a valid concern and there’s already an improvement ticket to address that.
Here’s another ticket to address the overall increase in package size.
Thank you for raising this issue. Mahi has pointed you to some relevant tickets in our backlog. Please comment, vote, and watch those tickets as that does help drive our planning process.
It would be helpful to understand your concerns about the increase in package size. In memory constrained environments like mobile devices, compilers will strip out unused code to reduce the total size of the executable. In your typical server application, a few extra MBs of assemblies is often not a concern. We would like to understand your use case where an increase from 17MB to 40MB caused you concern.
The Community could flip the question around somewhat and ask for what the design decision is to take in all the dependencies in one package, thereby causing users of your core package to get e.g. AWS dlls part of their deploys (even if not loaded or used). In this case licenses etc matches, but it’s still extra packages to keep track of seen to possible due diligence, licenses etc. I would expect the core stuff to be “this is what’s needed against native MongoDB environment”. If you want features for e.g. AWS, I would opt-in to that via a separate package.
Sorry for the late reply. One word microservices. Our applications use MongoDB as a sync for our logging system. This logging is used by every microservice we build and deploy. Each microservice is built and stored in a central repository and deployed dynamically to the application server. Linux in my case. Any given deployment can consist of 8-12 microservices. So going from 17 MB to 40 MB when fetching 12 microservice deployments makes a big difference in deployment/redeployment time.
The above is a objective rational too not wanting unused dependencies. Subjectively, it’s just not the right way to package an application.
Thank you for the feedback. Because NuGet does not support optional dependencies, we are left choosing between ease of use and minimizing total package size. The only way (that I am aware of) to minimize package size is to implement optional dependencies ourselves. This means detecting whether a package is present and dynamically loading it. We cannot simply have a reference between projects (and thus NuGet packages) and use the types from the other package. This complicates development and requires us to provide additional documentation e.g. If you want to use AWS authentication, you must reference the
MongoDB.Driver.AWS package. (NOTE:
MongoDB.Driver.AWS doesn’t exist and is simply an example.) This becomes even more complicated as you consider all the potential optional dependencies supported by the driver such as Kerberos, LDAP, GCP, Azure, and more.
In summary we have chosen to favour simplicity of use and simplicity of development over minimizing package size. If total package size is problematic for your application, CSHARP-4531 provides an example of how you can exclude unneeded dependencies via your package references.
As a user it would make perfect sense to opt-in to what you want. Like installing a meta package bringing in packages for the base line for “pure MongoDB” then e.g. Aws, Azure, GCP (like you have for e.g. auth) would be something I would expect to opt-in to. But of course. If the code in the core (as e.g. auth seem to be) is coupled to specific providers, I do understand that it’s hard to maintain.