The bash shell implements time as a keyword. The keyword is part of syntax of the pipeline.
The syntax of a pipeline in bash is (from the section entitled "Pipelines" in the bash manual):
[time [-p]] [!] command1 [ | or |& command2 ] …
Since time is part of the syntax of pipelines, not a shell built-in utility, it does not behave as a utility. For example, redirecting its output using ordinary shell redirections is not possible without extra trickery (see e.g. How can I redirect `time` output and command output to the same pipe?).
When the word time occurs in any other place than at the start of a pipeline in the bash shell, the external command with the same name will be called. This is what happens in the case when you put time after the pipe symbol, for example. If the shell can't find an external time command, it generates a "command not found" error.
To make the shell use the keyword to time only the sleep 1 command in your pipeline, you may use
echo foo | (time sleep 1)
Within the subshell on the right hand side of the pipeline, the time keyword is at the start of a pipeline (a pipeline of a single simple command, but still).
Also related:
timeis usually a shell built-in and an external program. Although on this system, the external command isn't installed for some reason. Also: I specifically want to time one part of the pipeline, not the entire thing. – MathematicalOrchid Jun 14 '21 at 10:16timeis not a shell built-in, but a keyword. See also How can we make `time` apply to a pipeline or its component? – Kusalananda Jun 14 '21 at 10:31time commandruns the shell keyword, butecho foo | time commandruns the binary. I can reproduce this on my Arch Linux system. And that is indeed surprising. – terdon Jun 14 '21 at 11:27timeis only allowed in certain places in the grammar. In particular, it's part of the syntax for a pipeline. It's specifically allowed at the start of a pipeline:[time [-p]] [ ! ] command [ | command2 … ]. Usingtimeat any other place would call the external utility. If there isn't one, then you get the obvious error message from the shell. – Kusalananda Jun 14 '21 at 11:45timein pipelines unspecified (stuff liketime a | b | canda | b | time c), likely exactly because some shells have it as a keyword that times the full pipeline, and some don't. "When time is used as part of a pipeline, the times reported are unspecified, except when it is the sole command within a grouping command" – ilkkachu Jun 14 '21 at 22:34