You've already forked immich
							
							
				mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 00:18:28 +02:00 
			
		
		
		
	chore: change default thumbnail concurrency and auto-detect container core count (#9981)
* feat: automatically detect amount of CPU cores and allow overriding with CPU_CORES env var * chore: change default thumbnail concurrency to 3
This commit is contained in:
		| @@ -4,6 +4,7 @@ | ||||
|  | ||||
| design/ | ||||
| docker/ | ||||
| !docker/scripts | ||||
| docs/ | ||||
| e2e/ | ||||
| fastlane/ | ||||
|   | ||||
							
								
								
									
										49
									
								
								docker/scripts/get-cpus.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										49
									
								
								docker/scripts/get-cpus.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| set -eu | ||||
|  | ||||
| LOG_LEVEL="${IMMICH_LOG_LEVEL:='info'}" | ||||
|  | ||||
| logDebug() { | ||||
|     if [ "$LOG_LEVEL" = "debug" ] || [ "$LOG_LEVEL" = "verbose" ]; then | ||||
|         echo "DEBUG: $1" >&2 | ||||
|     fi | ||||
| } | ||||
|  | ||||
| if [ -f /sys/fs/cgroup/cgroup.controllers ]; then | ||||
|     logDebug "cgroup v2 detected." | ||||
|     if [ -f /sys/fs/cgroup/cpu.max ]; then | ||||
|         read -r quota period </sys/fs/cgroup/cpu.max | ||||
|         if [ "$quota" = "max" ]; then | ||||
|             logDebug "No CPU limits set." | ||||
|             unset quota period | ||||
|         fi | ||||
|     else | ||||
|         logDebug "/sys/fs/cgroup/cpu.max not found." | ||||
|     fi | ||||
| else | ||||
|     logDebug "cgroup v1 detected." | ||||
|  | ||||
|     if [ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ] && [ -f /sys/fs/cgroup/cpu/cpu.cfs_period_us ]; then | ||||
|         quota=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us) | ||||
|         period=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us) | ||||
|  | ||||
|         if [ "$quota" = "-1" ]; then | ||||
|             logDebug "No CPU limits set." | ||||
|             unset quota period | ||||
|         fi | ||||
|     else | ||||
|         logDebug "/sys/fs/cgroup/cpu/cpu.cfs_quota_us or /sys/fs/cgroup/cpu/cpu.cfs_period_us not found." | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| if [ -n "${quota:-}" ] && [ -n "${period:-}" ]; then | ||||
|     cpus=$((quota / period)) | ||||
|     if [ "$cpus" -eq 0 ]; then | ||||
|         cpus=1 | ||||
|     fi | ||||
| else | ||||
|     cpus=$(grep -c processor /proc/cpuinfo) | ||||
| fi | ||||
|  | ||||
| echo "$cpus" | ||||
| @@ -19,6 +19,11 @@ this advice improves throughput, not latency, for example, it will make Smart Se | ||||
|  | ||||
| It is important to remember that jobs like Smart Search, Face Detection, Facial Recognition, and Transcode Videos require a **lot** of processing power and therefore do not exaggerate the amount of jobs because you're probably thoroughly overloading the server. | ||||
|  | ||||
| :::danger IMPORTANT | ||||
| If you increase the concurrency from the defaults we set, especially for thumbnail generation, make sure you do not increase them past the amount of CPU cores you have available. | ||||
| Doing so can impact API responsiveness with no gain in thumbnail generation speed. | ||||
| ::: | ||||
|  | ||||
| :::info Facial Recognition Concurrency | ||||
| The Facial Recognition Concurrency value cannot be changed because | ||||
| [DBSCAN](https://www.youtube.com/watch?v=RDZUdRSDOok) is traditionally sequential, but there are parallel implementations of it out there. Our implementation isn't parallel. | ||||
|   | ||||
| @@ -38,16 +38,17 @@ Regardless of filesystem, it is not recommended to use a network share for your | ||||
|  | ||||
| ## General | ||||
|  | ||||
| | Variable                        | Description                                     |         Default          | Containers               | Workers            | | ||||
| | :------------------------------ | :---------------------------------------------- | :----------------------: | :----------------------- | :----------------- | | ||||
| | `TZ`                            | Timezone                                        |                          | server                   | microservices      | | ||||
| | `IMMICH_ENV`                    | Environment (production, development)           |       `production`       | server, machine learning | api, microservices | | ||||
| | `IMMICH_LOG_LEVEL`              | Log Level (verbose, debug, log, warn, error)    |          `log`           | server, machine learning | api, microservices | | ||||
| | `IMMICH_MEDIA_LOCATION`         | Media Location                                  | `./upload`<sup>\*1</sup> | server                   | api, microservices | | ||||
| | `IMMICH_CONFIG_FILE`            | Path to config file                             |                          | server                   | api, microservices | | ||||
| | `IMMICH_WEB_ROOT`               | Path of root index.html                         |    `/usr/src/app/www`    | server                   | api                | | ||||
| | `IMMICH_REVERSE_GEOCODING_ROOT` | Path of reverse geocoding dump directory        |   `/usr/src/resources`   | server                   | microservices      | | ||||
| | `NO_COLOR`                      | Set to `true` to disable color-coded log output |         `false`          | server, machine learning |                    | | ||||
| | Variable                        | Description                                     |           Default            | Containers               | Workers            | | ||||
| | :------------------------------ | :---------------------------------------------- | :--------------------------: | :----------------------- | :----------------- | | ||||
| | `TZ`                            | Timezone                                        |                              | server                   | microservices      | | ||||
| | `IMMICH_ENV`                    | Environment (production, development)           |         `production`         | server, machine learning | api, microservices | | ||||
| | `IMMICH_LOG_LEVEL`              | Log Level (verbose, debug, log, warn, error)    |            `log`             | server, machine learning | api, microservices | | ||||
| | `IMMICH_MEDIA_LOCATION`         | Media Location                                  |   `./upload`<sup>\*1</sup>   | server                   | api, microservices | | ||||
| | `IMMICH_CONFIG_FILE`            | Path to config file                             |                              | server                   | api, microservices | | ||||
| | `IMMICH_WEB_ROOT`               | Path of root index.html                         |      `/usr/src/app/www`      | server                   | api                | | ||||
| | `IMMICH_REVERSE_GEOCODING_ROOT` | Path of reverse geocoding dump directory        |     `/usr/src/resources`     | server                   | microservices      | | ||||
| | `NO_COLOR`                      | Set to `true` to disable color-coded log output |           `false`            | server, machine learning |                    | | ||||
| | `CPU_CORES`                     | Amount of cores available to the immich server  | auto-detected cpu core count | server                   |                    | | ||||
|  | ||||
| \*1: With the default `WORKDIR` of `/usr/src/app`, this path will resolve to `/usr/src/app/upload`. | ||||
| It only need to be set if the Immich deployment method is changing. | ||||
|   | ||||
| @@ -54,6 +54,7 @@ COPY --from=web /usr/src/app/build ./www | ||||
| COPY server/resources resources | ||||
| COPY server/package.json server/package-lock.json ./ | ||||
| COPY server/start*.sh ./ | ||||
| COPY "docker/scripts/get-cpus.sh" ./ | ||||
| RUN npm link && npm install -g @immich/cli && npm cache clean --force | ||||
| COPY LICENSE /licenses/LICENSE.txt | ||||
| COPY LICENSE /LICENSE | ||||
|   | ||||
| @@ -240,7 +240,7 @@ export const defaults = Object.freeze<SystemConfig>({ | ||||
|     [QueueName.SIDECAR]: { concurrency: 5 }, | ||||
|     [QueueName.LIBRARY]: { concurrency: 5 }, | ||||
|     [QueueName.MIGRATION]: { concurrency: 5 }, | ||||
|     [QueueName.THUMBNAIL_GENERATION]: { concurrency: 5 }, | ||||
|     [QueueName.THUMBNAIL_GENERATION]: { concurrency: 3 }, | ||||
|     [QueueName.VIDEO_CONVERSION]: { concurrency: 1 }, | ||||
|     [QueueName.NOTIFICATION]: { concurrency: 5 }, | ||||
|   }, | ||||
|   | ||||
| @@ -42,7 +42,7 @@ const updatedConfig = Object.freeze<SystemConfig>({ | ||||
|     [QueueName.SIDECAR]: { concurrency: 5 }, | ||||
|     [QueueName.LIBRARY]: { concurrency: 5 }, | ||||
|     [QueueName.MIGRATION]: { concurrency: 5 }, | ||||
|     [QueueName.THUMBNAIL_GENERATION]: { concurrency: 5 }, | ||||
|     [QueueName.THUMBNAIL_GENERATION]: { concurrency: 3 }, | ||||
|     [QueueName.VIDEO_CONVERSION]: { concurrency: 1 }, | ||||
|     [QueueName.NOTIFICATION]: { concurrency: 5 }, | ||||
|   }, | ||||
|   | ||||
| @@ -17,4 +17,10 @@ read_file_and_export "DB_USERNAME_FILE" "DB_USERNAME" | ||||
| read_file_and_export "DB_PASSWORD_FILE" "DB_PASSWORD" | ||||
| read_file_and_export "REDIS_PASSWORD_FILE" "REDIS_PASSWORD" | ||||
|  | ||||
| export CPU_CORES="${CPU_CORES:=$(./get-cpus.sh)}" | ||||
| echo "Detected CPU Cores: $CPU_CORES" | ||||
| if [ "$CPU_CORES" -gt 4 ]; then | ||||
|   export UV_THREADPOOL_SIZE=$CPU_CORES | ||||
| fi | ||||
|  | ||||
| exec node /usr/src/app/dist/main "$@" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user